\begin{aosachapter}{Python Packaging}{s:packaging}{Tarek Ziad\'{e}}
%% Based on EN-Revision r375

%% \begin{aosasect1}{Introduction}
\begin{aosasect1}{はじめに}

%% There are two schools of thought when it comes to installing
%% applications.  The first, common to Windows and Mac OS X, is that
%% applications should be self-contained, and their installation should
%% not depend on anything else.  This philosophy simplifies the
%% management of applications: each application is its own standalone
%% ``appliance'', and installing and removing them should not disturb the
%% rest of the OS\@.  If the application needs an uncommon library, that
%% library is included in the application's distribution.
アプリケーションのインストールに関しては、ふたつの派閥がある。
ひとつは、「アプリケーション単体で完結させる」派だ。WindowsやMac OS X
で主流な考え方で、インストールのときに他の何かに依存するようではいけないというものだ。
この思想に従えば、アプリケーションの管理はシンプルになる。
各アプリケーションがそれ単体で動く``アプライアンス製品''で、
インストールやアンインストールをしてもOSには何ら影響を及ぼさない。
もしそのアプリケーションが特殊なライブラリを使うのなら、
ライブラリ自体もアプリケーションの配布物に含めることになる。

%% The second school, which is the norm for Linux-based systems, treats
%% software as a collection of small self-contained units called
%% \emph{packages}. Libraries are bundled into packages, any given
%% library package might depend on other packages.
%% Installing an application might involve finding and installing
%% particular versions of dozens of other libraries.  These dependencies
%% are usually fetched from a central repository that contains thousands
%% of packages.  This philosophy is why Linux distributions use complex
%% package management systems like \code{dpkg} and \code{RPM} to track
%% dependencies and prevent installation of two applications that use
%% incompatible versions of the same library.
もう一方の派閥は
「ソフトウェアとは、完結した小さな\emph{パッケージ}の集合体である」派で、
これはLinuxベースのシステムで主流である。ライブラリもパッケージとして同梱し、
そのライブラリパッケージが他のパッケージに依存する可能性もある。
何かのアプリケーションをインストールする際には、
何十個もの他のライブラリについて特定のバージョンを探してインストールする
ということだってある。こういった依存情報の取得は
中央リポジトリから取得することが多く、このリポジトリに
何千ものパッケージがまとまっている。
この思想があって、Linuxディストリビューションはそれぞれ複雑なパッケージ管理システム
(\code{dpkg}や\code{RPM}など)を使っている。
依存関係を追跡したり、同一ライブラリの互換性がない複数バージョン使う
アプリケーションの共存を防いだりなどといったことを行う。

%% There are pros and cons to each approach.  Having a highly modular
%% system where every piece can be updated or replaced makes management
%% easier, because each library is present in a single place, and all
%% applications that use it benefit when it is updated.  For instance, a
%% security fix in a particular library will reach all applications that
%% use it at once, whereas if an application ships with its own library,
%% that security fix will be more complex to deploy, especially if
%% different applications use different versions of the library.
どちらの手法にだって、利点もあれば欠点もある。
高度にモジュール化されたシステムで、すべてのパーツを個別に更新したり入れ替えたり
できるようにしておけば、管理は楽になる。各ライブラリは一か所にしか存在せず、
ライブラリを更新すればそれを使うすべてのアプリケーションがその恩恵を受けられるからである。
たとえば、何かのライブラリにセキュリティフィックスを適用すれば、
そのライブラリを使っているすべてのアプリケーションにその修正がいきわたる。
一方、各アプリケーションがライブラリ群を同梱して出荷する形式の場合、
セキュリティフィックスの適用がより複雑になる。
特に、さまざまなアプリケーションが同じライブラリの異なるバージョンを使っている場合などが大変だ。

%% But that modularity is seen as a drawback by some developers, because
%% they're not in control of their applications and dependencies.  It is
%% easier for them to provide a standalone software appliance to be sure
%% that the application environment is stable and not subject to
%% ``dependency hell'' during system upgrades.
しかし、そんなモジュール方式も、人によっては欠点だと感じることがある。
というのも、アプリケーションや依存関係をきちんと管理できなくなるからだ。
そんな人たちにとっては、単体で完結したソフトウェア製品を提供して
安定した環境を保証されるほうが安心する。システムの更新のときにも
「依存地獄」に悩まされずに済むからである。

%% Self-contained applications also make the developer's life easier when
%% she needs to support several operating systems.  Some projects go so
%% far as to release portable applications that remove \emph{any}
%% interaction with the hosting system by working in a self-contained
%% directory, even for log files.
自己完結方式のアプリケーションは、
複数のOSへのインストールに対応するのにも楽である。
プロジェクトによっては、完全にポータブルなアプリケーションをリリースすることもある。
導入先のシステムとの間のやりとりを\emph{一切}せずに
自分のディレクトリの中だけで動作するというものだ。
ログファイルでさえもこのディレクトリの中で完結する。

%% Python's packaging system was intended to make the second
%% philosophy---multiple dependencies for each install---as developer-,
%% admin-, packager-, and user-friendly as possible. Unfortunately it had
%% (and has) a variety of flaws which caused or allowed all kinds of
%% problems: unintuitive version schemes, mishandled data files,
%% difficulty re-packaging, and more.  Three years ago I and a group of
%% other Pythoneers decided to reinvent it to address these problems.  We
%% call ourselves the Fellowship of the Packaging, and this chapter
%% describes the problems we have been trying to fix, and what our
%% solution looks like.
Pythonのパッケージングシステムは、後者の思想(インストールごとに複数の依存関係が生じるもの)
に基づいて作られており、開発者にも管理者にもパッケージ作成者にも利用者にも
可能な限り使いやすくしようとしている。残念ながらさまざまな不具合があって、
考えうる限りのいろんな問題がこれまでに発生してきた(というか、今もなお発生している)。
「バージョンスキーマがわかりにくい」「データファイルの処理を間違える」
「パッケージの再作成が難しい」などなど。
三年前、私を含むPython開発者グループは、
これらの課題に対応すべく新たな仕組みの開発に乗り出し、
「パッケージングの仲間」を名乗った。
\footnote{訳注: ``the Fellowship of the Packaging''。
元ネタは『指輪物語』の``The Fellowship of the Ring''か。}
本章では、私たちがこれまでに解決しようとした問題や
どんなふうに問題を解決したのかを解説する。

%% \begin{aosabox}{Terminology}
\begin{aosabox}{用語}

%% In Python a \emph{package} is a directory containing Python
%% files. Python files are called \emph{modules}.  That definition makes
%% the usage of the word ``package'' a bit vague since it is also used by
%% many systems to refer to a \emph{release} of a project.
Pythonの世界では、\emph{パッケージ}といえばPythonファイルを含むディレクトリのことである。
Pythonファイルのことは\emph{モジュール}と呼ぶ。そんなこともあって、
``パッケージ''という言葉を使うときには少し曖昧な感じになってしまう。
というのも、多くのシステムではプロジェクトの\emph{リリース}
のこともパッケージと呼ぶからである。

%% Python developers themselves are sometimes vague about this.  One way
%% to remove this ambiguity is to use the term ``Python packages'' when
%% we talk about a directory containing Python modules.  The term
%% ``release'' is used to define one version of a project, and the term
%% ``distribution'' defines a source or a binary distribution of a
%% release as something like a tarball or zip file.
Python開発者ですら、ときどき混乱することがある。
紛らわしさを排除する方法のひとつは、Pythonモジュールを含むディレクトリを指すときには
「Pythonパッケージ」と言うようにすることだ。
「リリース」は何かのプロジェクトのひとつのバージョンを表す用語として使い、
あるリリースのソースあるいはバイナリをtarやzipでまとめたもののことを
「ディストリビューション(配布物)」と呼ぶことにする。

\end{aosabox}

\end{aosasect1}

%% \begin{aosasect1}{The Burden of the Python Developer}
\begin{aosasect1}{Python開発者の苦悩}

%% Most Python programmers want their programs to be usable in any
%% environment.  They also usually want to use a mix of standard Python
%% libraries and system-dependent libraries.  But unless you package your
%% application separately for every existing packaging system, you are
%% doomed to provide Python-specific releases---a Python-specific release
%% is a release aimed to be installed within a Python installation no
%% matter what the underlying Operating System is---and hope that:
Pythonプログラマーなら誰だって、自分のプログラムをいろんな環境で使えるようにしたいものだ。
また、標準のPythonrライブラリとシステム依存のライブラリを組み合わせて使いたいことも多い。
しかし、既存のすべてのパッケージングシステム用にそれぞれ個別のパッケージを作るのでもなければ、
Python用のリリース---つまり、
OSが何であるかにかかわらず、Pythonをインストールした環境に導入することを狙いとしたリリース
---を作って、後はこんなことを願うしかなくなる。

\begin{aosaitemize}

  %% \item packagers for every target system will be able to repackage
  %% your work,
  \item すべての対象システムのパッケージ担当者が、個別のシステム用にパッケージを作り直せるようにする

  %% \item the dependencies you have will themselves be repackaged in
  %% every target system, and
  \item 依存関係も、すべての対象システムで再パッケージできるようにする

  %% \item system dependencies will be clearly described.
  \item システムの依存関係をきちんと表せる

\end{aosaitemize}

%% Sometimes, this is simply impossible.  For example, Plone (a
%% full-fledged Python-powered CMS) uses hundreds of small pure Python
%% libraries that are not always available as packages in every packaging
%% system out there.  This means that Plone \emph{must} ship everything
%% that it needs in a portable application. To do this, it uses
%% \code{zc.buildout}, which collects all its dependencies and creates a
%% portable application that will run on any system within a single
%% directory. It is effectively a binary release, since any piece of C
%% code will be compiled in place.
そもそもそんなことは不可能だという場合もある。
たとえばPlone(Python製の本格的なCMS)は、
ピュアPythonの小さなライブラリを何百も使っている。
いま出回っている各種パッケージングシステムで、
これらのライブラリがすべてパッケージ化されているとは限らない。
つまりPloneの場合は、必要なものをすべて同梱して
それ単体で機能するアプリケーションに\emph{せざるを得ない}ということだ。
そのために、Ploneでは\code{zc.buildout}を使っている。
これは、すべての依存情報を収集してポータブルなアプリケーションを作り、
そのディレクトリ単体だけであらゆるシステムで実行できるようにする仕組みだ。
これは事実上、バイナリリリースに等しい。
Cのコードもすべてコンパイル済みだからである。

%% This is a big win for developers: they just have to describe their
%% dependencies using the Python standards described below
%% and use \code{zc.buildout} to
%% release their application.  But as discussed earlier, this type of
%% release sets up a fortress within the system, which most Linux sysadmins
%% will hate.  Windows admins won't mind, but those managing
%% CentOS or Debian will, because those systems base their management on
%% the assumption that every file in the system is registered,
%% classified, and known to admin tools.
この方式は、開発者にとっては大勝利と言えるだろう。
後述するPythonの標準規格にしたがって依存関係を記述しておきさえすれば、あとは
\code{zc.buildout}を使えばアプリケーションをリリースできるのだから。
しかし、先述のとおり、この形式のリリースは
システムの中に要塞を構築するのに等しい。
たいていのLinuxシステム管理者は、この方式を嫌うだろう。
Windowsの管理者は別に気にしないかもしれない。でも
CentOSやDebianの管理者にとっては一大事だ。
というのも彼らにとっては、システム上のすべてのファイルが
ベースとなる管理システムに登録されていることが前提であり、
すべてのファイルを管理ツールで管理できることが前提だからである。

%% Those admins will want to repackage your application according to
%% their own standards.  The question we need to answer is, ``Can Python
%% have a packaging system that can be automatically translated into
%% other packaging systems?''  If so, one application or library can be
%% installed on any system without requiring extra packaging work.  Here,
%% ``automatically'' doesn't necessarily mean that the work should be
%% fully done by a script: \code{RPM} or \code{dpkg} packagers will tell
%% you that's impossible---they always need to add some specifics in the
%% projects they repackage.  They'll also tell you that they
%% often have a hard time re-packaging a piece of code because its
%% developers were not aware of a few basic packaging rules.
彼らは、あなたの作ったアプリケーションを自分たちの流儀に沿ってパッケージしなおそうとするかもしれない。
ここで問われるのは
「Pythonで、他のパッケージングシステムにも自動変換できるようなパッケージングシステムって作れないの?」
ということだ。もしそれが実現できれば、
特に追加作業をしなくてもひとつのアプリケーションやライブラリをあらゆるシステムにインストールできるようになる。
ここで言う「自動化」は、必ずしもすべての作業をスクリプトで済ませるということではない。
\code{RPM}や\code{dpkg}のパッケージを作っている人に聞いてみよう。
そんなの不可能だってことがわかるはずだ。
彼らはいつも、パッケージを作り直すときにちょっとした手作業が必要になっている。
あと、こんなことも教えてくれるだろう。
「何かコードをパッケージしなおすってのは大変なんだよ。だって、
開発者ときたら、パッケージングのときのお約束なんてこれっぽっちも気にしないんだから」

%% Here's one example of what you can do to annoy packagers using the
%% existing Python packaging system: release a library called
%% ``MathUtils'' with the version name ``Fumanchu''.  The brilliant
%% mathematician who wrote the library have found it amusing to use
%% his cats' names for his project versions.  But how can a packager know
%% that ``Fumanchu'' is his second cat's name, and that the first one was
%% called ``Phil'', so that the ``Fumanchu'' version comes after the
%% ``Phil'' one?
既存のPythonパッケージングシステムを使うパッケージャーを困らせる方法をひとつ教えよう。
``MathUtils''という名前のライブラリの、バージョン``Fumanchu''リリースするんだ。
どこかの賢い数学者がライブラリを書いたときに、
「バージョン番号のかわりに、うちの飼い猫の名前を順番につけていこう。イケてるよね？」
とでも思ったんでしょうなあ。
実は``Fumanchu''っていうのは二番目の猫の名前で、最初の猫は``Phil''だったんだ。
つまり、``Fumanchu''は``Phil''の次のバージョンなんだけど、
そんなことパッケージャーが知るわけがない。

%% This may sound extreme, but it can happen with today's tools and
%% standards.  The worst thing is that tools like \code{easy\_install} or
%% \code{pip} use their own non-standard registry to keep track of
%% installed files, and will sort the ``Fumanchu'' and ``Phil'' versions
%% alphanumerically.
いくらなんでも極端すぎると思うかもしれないが、いまどきのツールや標準規約を
使っていると、十分起こり得ることだ。
最悪なのは、\code{easy\_install}や\code{pip}といったツールが
それぞれ非標準のレジストリを自前で持っており、
インストールしたファイルをそこで管理しているってことだ。
そこでは、``Fumanchu''や``Phil''といったバージョン名はアルファベット順に並んでしまう。

%% Another problem is how to handle data files.  For example, what if
%% your application uses an SQLite database?  If you put it inside your
%% package directory, your application might fail because the system
%% forbids you to write in that part of the tree.  Doing this will
%% also compromise the assumptions Linux systems make about where
%% application data is for backups (\code{/var}).
もうひとつ問題がある。データファイルの扱いをどうするかということだ。
たとえば、もしあなたのアプリケーションでSQLiteデータベースを使うとしたらどうだろう?
もしパッケージディレクトリの中にデータベースを置いたら、アプリケーションはうまく動かないかもしれない。
アプリケーションを実行する人には、ツリー内のその部分に対する書き込み権限がないかもしれないからだ。
それだけでなく、Linuxシステムでの前提も崩してしまう。Linuxシステム上では、
バックアップ対象になるアプリケーションのデータを\code{/var}に置くことになっているのだ。

%% In the real world, system administrators need to be able to place your
%% files where they want without breaking your application, and you need
%% to tell them what those files are.  So let's rephrase the question: is
%% it possible to have a packaging system in Python that can provide all
%% the information needed to repackage an application with any
%% third-party packaging system out there without having to read the
%% code, and make everyone happy?
実際には、システム管理者がアプリケーションのファイルを好きなところに
置けるようにする必要がある。それでアプリケーションが動かなくなることがあってはならず、
アプリケーションのファイルがどこにあるかを管理者に伝えなければならない。
そこで、先ほどの質問をこう言い換えてみよう。
「Pythonで、こんなパッケージングシステムは実現可能だろうか?
サードパーティのパッケージングシステムがパッケージを作り直すときに、
わざわざアプリケーションのコードを追う必要がなく、みんなが幸せになれるようなシステムを」

\end{aosasect1}

%% \begin{aosasect1}{The Current Architecture of Packaging}
\begin{aosasect1}{現在のパッケージングのアーキテクチャ}

%% The \code{Distutils} package that comes with the Python standard
%% library is riddled with the problems described above.  Since it's the
%% standard, people either live with it and its flaws, or use more
%% advanced tools like \code{Setuptools}, which add features on the top of it,
%% or \code{Distribute}, a fork of \code{Setuptools}. There's also \code{Pip},
%% a more advanced installer, that relies on \code{Setuptools}.
\code{Distutils}パッケージがPython標準ライブラリとして組み込まれている。
これは、先述の問題たちに対応するために用意された。
標準で組み込まれているので、問題はあるけれどもそれを使っているという人もいる。
あるいは、もっとよくできた\code{Setuptools}などのツールを使う人もいる。
これは\code{Distutils}に機能を追加したものだ。
あるいは、\code{Setuptools}のフォークである\code{Distribute}という選択肢もある。
さらに、もっと高機能なインストーラーとして\code{Pip}
も存在する。これは\code{Setuptools}に依存している。

%% However, these newer tools are all based on \code{Distutils} and inherit its
%% problems.  Attempts were made to fix \code{Distutils} in place, but
%% the code is so deeply used by other tools that any change to it, even
%% its internals, is a potential regression in the whole Python packaging
%% ecosystem.
しかし、これらのツールはすべて\code{Distutils}をベースにしたものであり、
その問題点も引き継いでいる。\code{Distutils}自体を改善しようという動きもあったが、
他のツールがあまりにもそのコードに依存しすぎていたので、
内部のコードをほんの少し変更するだけでもPythonpパッケージの世界を破滅させてしまう恐れがあった。

%% We therefore decided to freeze \code{Distutils} and start the
%% development of \code{Distutils2} from the same code base, without
%% worrying too much about backward compatibility.  To understand what
%% changed and why, let's have a closer look at \code{Distutils}.
そこで私たちは、\code{Distutils}の開発を停止して、同じコードベースで\code{Distutils2}
の開発を新たに始めた。これで後方互換性を気にせずに済む。
何を変えたのか、なぜ変えたのか。それを理解するために、まずは\code{Distutils}
について詳しく見ていこう。

%% \begin{aosasect2}{Distutils Basics and Design Flaws}
\begin{aosasect2}{Distutilsの基本とその設計ミス}
\label{sec.packaging.flaws}

%% \code{Distutils} contains commands, each of which is a class with a
%% \code{run} method that can be called with some options.  \code{Distutils}
%% also provides a \code{Distribution} class that contains global values
%% every command can look at.
\code{Distutils}に含まれるコマンド群はどれも、\code{run}メソッドを持つクラスである。
いろんなオプションを指定して呼べる。
\code{Distutils}では\code{Distribution}クラスも提供しており、
ここに格納されているグローバルな値は全コマンドから参照できる。

%% To use \code{Distutils}, a developer adds a single Python module to a
%% project, conventionally called \code{setup.py}. This module contains a
%% call to \code{Distutils}' main entry point: the \code{setup} function.  This
%% function can take many options, which are held by a
%% \code{Distribution} instance and used by commands.  Here's an example
%% that defines a few standard options like the name and version of the
%% project, and a list of modules it contains:
\code{Distutils}を使いたい開発者は、自分のプロジェクトにPythonモジュールをひとつ
追加すればよい。慣例的に、名前は\code{setup.py}とすることになっている。
このモジュールで、\code{Distutils}のエントリポイントである\code{setup}関数を呼び出す。
この関数にはいろんなオプションを指定できる。指定したオプションは、\code{Distribution}
で保持してコマンドから使えるようになる。ひとつ例を示そう。
ここでは、標準的なオプションをいくつか定義している。
プロジェクトの名前とバージョン、そして含まれるモジュールの一覧だ。

\pagebreak

\begin{verbatim}
from distutils.core import setup

setup(name='MyProject', version='1.0', py_modules=['mycode.py'])
\end{verbatim}

%% \noindent This module can then be used to run \code{Distutils} commands like
%% \code{sdist}, which creates a source distribution in an archive and
%% places it in a \code{dist} directory:
\noindent
このモジュールを使えば\code{Distutils}のコマンドを実行できる。
たとえば\code{sdist}は、ソースディストリビューションをアーカイブして\code{dist}ディレクトリに置く。

\begin{verbatim}
$ python setup.py sdist
\end{verbatim}

%% \noindent Using the same script, you can install the project using the
%% \code{install} command:
\noindent
同じスクリプトを使って、\code{install}コマンドでこのプロジェクトをインストールすることもできる。

\begin{verbatim}
$ python setup.py install
\end{verbatim}

%% \code{Distutils} provides other commands such as:
\code{Distutils}には、それ以外にもこんなコマンドがある。

\begin{aosaitemize}

  %% \item \code{upload} to upload a distribution into an online repository.
  \item \code{upload}…ディストリビューションをオンラインリポジトリにアップロードする。

  %% \item \code{register} to register the metadata of a project in an online
  %% repository without necessary uploading a distribution,
  \item \code{register}…プロジェクトのメタデータをオンラインリポジトリに登録する。
  このときに必ずしもディストリビューションをアップロードする必要はない。

  %% \item \code{bdist} to creates a binary distribution, and
  \item \code{bdist}…バイナリディストリビューションを作成する。

  %% \item \code{bdist\_msi} to create a \code{.msi} file for Windows.
  \item \code{bdist\_msi}…Windows用の\code{.msi}ファイルを作成する。

\end{aosaitemize}

%% \noindent
%% It will also let you get information about the project via other
%% command line options.
\noindent
また、プロジェクトに関する情報をコマンドラインオプションで取得することもできる。

%% So installing a project or getting information about it is always done
%% by invoking \code{Distutils} through this file. For example, to find
%% out the name of the project:
つまり、このプロジェクトをインストールしたり情報を調べたりといった作業は、
ぜんぶこのファイルを使って\code{Distutils}経由で行える。
たとえば、プロジェクトの名前を調べるには次のようにする。

\begin{verbatim}
$ python setup.py --name
MyProject
\end{verbatim}

%% \noindent \code{setup.py} is therefore how everyone interacts with the project,
%% whether to build, package, publish, or install it. The developer
%% describes the content of his project through options passed to a
%% function, and uses that file for all his packaging tasks. The file is
%% also used by installers to install the project on a target system.
\noindent
つまり\code{setup.py}は、プロジェクトに関して何かをしたいときに常に
間に入るものだということだ。ビルドからパッケージ作成、公開、インストールに至るまですべてである。
開発者はプロジェクトの内容を関数へのオプションで指定し、
また、このファイルを使ってパッケージ作成の作業もこなす。
このファイルはまた、導入先のシステムでプロジェクトをインストールするときにも使われる。

%% \aosafigure[300pt]{../images/packaging/setup-py.eps}{Setup}{fig.packaging.setup}
\aosafigure[300pt]{../images/packaging/setup-py.eps}{Setup}{fig.packaging.setup}

%% Having a single Python module used for packaging, releasing,
%% \emph{and} installing a project is one of \code{Distutils}' main
%% flaws.  For example, if you want to get the \code{name} from the \code{lxml}
%% project, \code{setup.py} will do a lot of things besides returning a
%% simple string as expected:
たったひとつのPythonモジュールでパッケージ作成やらリリースやら
\emph{挙句の果てには}インストールまでさせてしまう、というのが
\code{Distutils}の問題のひとつだ。
たとえば\code{lxml}プロジェクトの名前を取得したいとしよう。
\code{setup.py}は、単に名前を文字列で返す以外にもいろんなことをする。

\begin{verbatim}
$ python setup.py --name
Building lxml version 2.2.
NOTE: Trying to build without Cython, pre-generated 'src/lxml/lxml.etree.c'
needs to be available.
Using build configuration of libxslt 1.1.26
Building against libxml2/libxslt in the following directory: /usr/lib/lxml
\end{verbatim}

%% \noindent It might even fail to work on some projects, since
%% developers make the assumption that \code{setup.py} is used only to
%% install, and that other \code{Distutils} features are only used by
%% them during development.  The multiple roles of the \code{setup.py}
%% script can easily cause confusion.
\noindent
場合によってはこれがうまく動かないかもしれない。
「\code{setup.py}なんて、インストールのときにしか使わないよね」
と思いこんだ開発者が、それ以外の\code{Distutils}の機能を
ユーザーが使うとは想定していないような場合がある。
\code{setup.py}にいろんな役割を持たせてしまうのは混乱のもとだ。

\end{aosasect2}

%% \begin{aosasect2}{Metadata and PyPI}
\begin{aosasect2}{MetadataとPyPI}

%% When \code{Distutils} builds a distribution, it creates a
%% \code{Metadata} file that follows the standard described in
%% PEP~314\footnote{The Python Enhancement Proposals, or PEPs, that we
%% refer to are summarized at the end of this chapter}.  It contains a
%% static version of all the usual metadata, like the name of the project
%% or the version of the release.  The main metadata fields are:
\code{Distutils}は、ディストリビューションを作るときに\code{Metadata}
ファイルも作る。これは、PEP~314
\footnote{Python Enhancement Proposals(本章ではPEPと略する)については、
本章の最後にまとめる}
で指定された標準規約に従うものである。
その中に含まれるのは通常のメタデータ、たとえばプロジェクト名や
リリースのバージョンなどである。主要なフィールドを以下に示す。

\begin{aosaitemize}

  %% \item \code{Name}: The name of the project.
  \item \code{Name}: プロジェクト名。

  %% \item \code{Version}: The version of the release.
  \item \code{Version}: リリースのバージョン。

  %% \item \code{Summary}: A one-line description.
  \item \code{Summary}: 一行にまとめた説明。

  %% \item \code{Description}: A detailed description.
  \item \code{Description}: 詳しい説明。

  %% \item \code{Home-Page}: The URL of the project.
  \item \code{Home-Page}: プロジェクトのURL。

  %% \item \code{Author}: The author name.
  \item \code{Author}: 作者名。

  %% \item \code{Classifiers}: Classifiers for the project. Python provides a list
  %% of classifiers for the license, the maturity of the release (beta,
  %% alpha, final), etc.
  \item \code{Classifiers}: プロジェクトの分類。
  使える分類の一覧はPythonが用意しており、たとえばライセンスや
  リリースの成熟度(beta、alpha、final)などを指定できる。

  %% \item \code{Requires}, \code{Provides}, and \code{Obsoletes}:
  %% Used to define dependencies with modules.
  \item \code{Requires}、\code{Provides}、\code{Obsoletes}: モジュールの依存関係。

\end{aosaitemize}

%% \noindent
%% These fields are for the most part easy to map to equivalents in other
%% packaging systems.
\noindent
これらの項目の大半は、他のパッケージシステムにも同様なものが用意されているので簡単に対応できる。

%% The Python Package Index (PyPI)\footnote{Formerly known as the
%% CheeseShop.}, a central repository of packages like CPAN, is able to
%% register projects and publish releases via \code{Distutils}'
%% \code{register} and \code{upload} commands.  \code{register} builds
%% the \code{Metadata} file and sends it to PyPI, allowing people and
%% tools---like installers---to browse them via web pages or via web
%% services.
Python Package Index (PyPI)\footnote{かつてCheeseShopと呼ばれていたもの。}は、
CPANのようにパッケージを取りまとめた中央リポジトリである。
ここにプロジェクトを登録したりリリースを公開したりするには
\code{Distutils}の\code{register}コマンドや\code{upload}コマンドを使えばよい。
\code{register}は、\code{Metadata}ファイルを構築してPyPIに送信する。
これで、利用者やツール(インストーラなど)がそのパッケージを
(ウェブページやウェブサービス経由で)見つけられるようになる。

%% \aosafigure[400pt]{../images/packaging/pypi.eps}{The PyPI Repository}{fig.packaging.pypi}
\aosafigure[400pt]{../images/packaging/pypi.eps}{PyPIリポジトリ}{fig.packaging.pypi}

%% You can browse projects by \code{Classifiers}, and get the author name
%% and project URL\@.  Meanwhile, \code{Requires} can be used to define
%% dependencies on Python modules.  The \code{requires} option can be
%% used to add a \code{Requires} metadata element to the project:
\code{Classifiers}にもとづいてプロジェクトを閲覧し、
その作者名やプロジェクトのURLを取得することができる。
一方、\code{Requires}を使えばPythonモジュールとの依存関係を定義できる。
\code{requires}オプションを使って、プロジェクトに\code{Requires}メタデータ要素を追加できる。

\begin{verbatim}
from distutils.core import setup

setup(name='foo', version='1.0', requires=['ldap'])
\end{verbatim}

%% Defining a dependency on the \code{ldap} module is purely declarative:
%% no tools or installers ensure that such a module exists.  This would be
%% satisfactory if Python defined requirements at the module level
%% through a \code{require} keyword like Perl does.  Then it would
%% just be a matter of the installers browsing the dependencies at PyPI
%% and installing them; that's basically what CPAN does.  But that's not
%% possible in Python since a module named \code{ldap} can exist in any
%% Python project. Since \code{Distutils} allows people to release
%% projects that can contain several packages and modules, this metadata
%% field is not useful at all.
\code{ldap}モジュールに対する依存関係の定義は純粋に宣言的なものであり、
インストーラーやツールでそのモジュールの存在を保証できるわけではない。
Pythonが依存関係をモジュールレベルで定義できるのなら、これでも十分だ。
そう、ちょうどPerlの\code{require}キーワードみたいにね。
そうすれば、インストーラーは単にPyPIで依存情報を確認してそれをインストールするだけになる。
CPANがやっているのは、基本的にそういうことだ。
でもPythonではそれができない。というのも、\code{ldap}
という名前のモジュールはあらゆるPythonプロジェクトに存在する可能性があるからである。
\code{Distutils}では複数のパッケージやモジュールを含むプロジェクトをリリースできるので、
このメタデータフィールドはまったく使い物にならない。

%% Another flaw of \code{Metadata} files is that they are created by a
%% Python script, so they are specific to the platform they are executed
%% in.  For example, a project that provides features specific to Windows
%% could define its \code{setup.py} as:
\code{Metadata}ファイルには、それ以外の問題もある。
このファイルはPythonスクリプトで作られるので、
スクリプトを実行したプラットフォーム専用のものになってしまうのだ。
たとえば、Windows専用の機能を提供するプロジェクトでは、\code{setup.py}
で次のような定義をすることになるだろう。

\begin{verbatim}
from distutils.core import setup

setup(name='foo', version='1.0', requires=['win32com'])
\end{verbatim}

%% \noindent But this assumes that the project only works under Windows, even if it
%% provides portable features.  One way to solve this is to make the
%% \code{requires} option specific to Windows:
\noindent
しかしこれでは、たとえ実際には他のプラットフォームでも同じ機能が使える場合でも、
このプロジェクトはWindowsでしか動かないということになってしまう。
ひとつの解決策として、Windowsの場合だけ\code{requires}オプションを指定するという方法もある。

\begin{verbatim}
from distutils.core import setup
import sys
\end{verbatim}
\begin{verbatim}
if sys.platform == 'win32':
    setup(name='foo', version='1.0', requires=['win32com'])
else:
    setup(name='foo', version='1.0')
\end{verbatim}

%% \noindent This actually makes the issue worse. Remember, the script is used to
%% build source archives that are then released to the world via PyPI.
%% This means that the static \code{Metadata} file sent to PyPI is
%% dependent on the platform that was used to compile it.  In other
%% words, there is no way to indicate statically in the metadata field
%% that it is platform-specific.
\noindent
しかし、そんなことをすれば問題はさらに悪化する。
思い出してみよう。このスクリプトは、PyPI経由で世に送り出すための
ソースアーカイブを作るときにも使うものだった。
つまり、PyPIに送られる\code{Metadata}ファイルは、
コンパイルしたプラットフォームに依存するものになってしまう。
つまり、プラットフォームによって値が異なるようなメタデータフィールドを
用意するのは不可能だということである。

\end{aosasect2}

%% \begin{aosasect2}{Architecture of PyPI}
\begin{aosasect2}{PyPIのアーキテクチャ}

%% \aosafigure[250pt]{../images/packaging/pypi-workflow.eps}{PyPI Workflow}{fig.packaging.workflow}
\aosafigure[250pt]{../images/packaging/pypi-workflow.eps}{PyPIのワークフロー}{fig.packaging.workflow}

%% As indicated earlier, PyPI is a central index of Python projects where
%% people can browse existing projects by category or register their own
%% work.  Source or binary distributions can be uploaded and added to an
%% existing project, and then downloaded for installation or study.  PyPI
%% also offers web services that can be used by tools like installers.
先述のとおり、PyPIはPythonのプロジェクトをまとめた索引である。
カテゴリを指定してプロジェクトを探したり、自分のプロジェクトを登録したりできる。
ソースディストリビューションやバイナリディストリビューションをアップロードして
プロジェクトに追加すれば、それを他の人がダウンロードしてインストールできるようになる。
PyPIはウェブサービスも提供しており、インストーラなどのツールはこのサービスを利用する。

%% \begin{aosasect3}{Registering Projects and Uploading Distributions}
\begin{aosasect3}{プロジェクトの登録とディストリビューションのアップロード}

%% Registering a project to PyPI is done with the \code{Distutils}
%% \code{register} command.  It builds a POST request containing the
%% metadata of the project, whatever its version is.  The request
%% requires an Authorization header, as PyPI uses Basic Authentication to
%% make sure every registered project is associated with a user that has
%% first registered with PyPI\@.  Credentials are kept in the local
%% \code{Distutils} configuration or typed in the prompt every time a
%% \code{register} command is invoked.  An example of its use is:
プロジェクトをPyPIに登録するには、\code{Distutils}の\code{register}コマンドを使う。
このコマンドは、プロジェクトのメタデータやバージョンを含むPOSTリクエストを作る。
このリクエストにはAuthorizationヘッダが必要となる。
というのもPyPIは、最初にプロジェクトを登録した人と同一ユーザーであるかどうかを
確認するためにベーシック認証を使っているからである。
認証情報はローカルの\code{Distutils}の設定に保存することもできるし、
\code{register}コマンドを実行するたびに入力することもできる。
使い方は、次のようになる。

\begin{verbatim}
$ python setup.py register
running register
Registering MPTools to http://pypi.python.org/pypi
Server response (200): OK
\end{verbatim}

%% \noindent Each registered project gets a web page with an HTML version of the
%% metadata, and packagers can upload distributions to PyPI using
%% \code{upload}:
\noindent
プロジェクトを登録すると、そのプロジェクト用のウェブページに
メタデータのHTMLバージョンが表示される。
ディストリビューションをPyPIにアップロードするには
\code{upload}を使う。

\begin{verbatim}
$ python setup.py sdist upload
running sdist
...
running upload
Submitting dist/mopytools-0.1.tar.gz to http://pypi.python.org/pypi
Server response (200): OK
\end{verbatim}

%% It's also possible to point users to another location via the
%% \code{Download-URL} metadata field rather than uploading files directly to PyPI.
ファイルを直接PyPIにアップロードするかわりに、
別の場所を使うよう指定することもできる。その場合は、
メタデータの\code{Download-URL}フィールドを指定する。

\end{aosasect3}

%% \begin{aosasect3}{Querying PyPI}
\begin{aosasect3}{PyPIへの問い合わせ}

%% Besides the HTML pages PyPI publishes for web users, it provides two
%% services that tools can use to browse the content: the Simple Index
%% protocol and the XML-RPC APIs.
PyPIは、ウェブ経由での利用者向けにHTMLページを作るだけでなく、
ふたつのサービスも提供する。Simple Indexプロトコルと
XML-RPC APIだ。

%% The Simple Index protocol starts at
%% \url{http://pypi.python.org/simple/}, a plain HTML page that contains
%% relative links to every registered project:
Simple Indexプロトコルは\url{http://pypi.python.org/simple/}
から始まるプレーンなHTMLページで、登録されている全プロジェクトへの
相対リンクを含む。

\begin{verbatim}
<html><head><title>Simple Index</title></head><body>
...
<a href='MontyLingua/'>MontyLingua</a><br/>
<a href='mootiro_web/'>mootiro_web</a><br/>
<a href='Mopidy/'>Mopidy</a><br/>
<a href='mopowg/'>mopowg</a><br/>
<a href='MOPPY/'>MOPPY</a><br/>
<a href='MPTools/'>MPTools</a><br/>
<a href='morbid/'>morbid</a><br/>
<a href='Morelia/'>Morelia</a><br/>
<a href='morse/'>morse</a><br/>
...
</body></html>
\end{verbatim}

%% \noindent For example, the MPTools project has a \code{MPTools/} link, which
%% means that the project exists in the index.  The site it points at
%% contains a list of all the links related to the project:
\noindent
たとえばMPToolsプロジェクトには\code{MPTools/}というリンクがある。
これは、そのプロジェクトがインデックスに存在することを意味する。
リンク先のサイトに、そのプロジェクトに関連するすべてのリンクが含まれる。

\begin{aosaitemize}

  %% \item links for every distribution stored at PyPI
  \item PyPI に格納されているすべてのディストリビューションへのリンク

  %% \item links for every Home URL defined in the \code{Metadata}, for
  %% each version of the project registered
  \item 登録されている各バージョンについての、\code{Metadata}で定義されたすべてのホームURL

  %% \item links for every Download-URL defined in the \code{Metadata}, for
  %% each version as well.
  \item 同じく登録されている各バージョンについての、\code{Metadata}で定義されたすべてのダウンロードURL

\end{aosaitemize}

%% \noindent
%% The page for MPTools contains:
\noindent
MPToolsのページの内容は、このようになる。

\begin{verbatim}
<html><head><title>Links for MPTools</title></head>
<body><h1>Links for MPTools</h1>
<a href="../../packages/source/M/MPTools/MPTools-0.1.tar.gz">MPTools-0.1.tar.gz</a><br/>
<a href="http://bitbucket.org/tarek/mopytools" rel="homepage">0.1 home_page</a><br/>
</body></html>
\end{verbatim}

%% \noindent
%% Tools like installers that want to find distributions of a project can
%% look for it in the index page, or simply check if
%% \url{http://pypi.python.org/simple/PROJECT_NAME/} exists.
\noindent
インストーラなどのツールがプロジェクトのディストリビューションを探したいときは、
インデックスページを調べるか、あるいは単に\url{http://pypi.python.org/simple/PROJECT_NAME/}
が存在するかどうかを調べればよい。

%% This protocol has two main limitations.  First, PyPI is a single
%% server right now, and while people usually have local copies of its
%% content, we have experienced several downtimes in the past two years
%% that have paralyzed developers that are constantly working with
%% installers that browse PyPI to get all the dependencies a project
%% requires when it is built. For instance, building a Plone application
%% will generate several hundreds queries at PyPI to get all the required
%% bits, so PyPI may act as a single point of failure.
このプロトコルには、ふたつの大きな制限がある。
まず第一に、PyPIは現時点では単一のサーバーで運用しているということ。
多くの人はそのコンテンツをローカルにコピーしているが、
過去二年間にも何度かPyPIがダウンすることがあった。
そのたびに、PyPIを見てプロジェクトの依存関係を解決する
インストーラが使えなくなって開発者を混乱させていた。
たとえば、Ploneアプリケーションをビルドするときには
PyPIへの問い合わせが数百件単位で発生する。
必要なパッケージを取得するためである。
つまり、PyPIが単一障害点となる可能性があるわけだ。

%% Second, when the distributions are not stored at PyPI and a
%% Download-URL link is provided in the Simple Index page, installers
%% have to follow that link and hope that the location will be up and
%% will really contain the release. These indirections weakens any Simple
%% Index-based process.
そして第二に、ディストリビューションをPyPIに格納せずに
Simple IndexページでDownload-URLのリンクを提供している場合、
インストーラはそのリンクをたどることになる。
その場所が正常稼働中なのか、そこにブツが本当にあるのかを気にしながら。
こういった回り道が、Simple Indexベースのすべての処理の弱点となる。

%% The Simple Index protocol's goal is to give to installers a list of
%% links they can use to install a project. The project metadata is not
%% published there; instead, there are XML-RPC methods to get extra
%% information about registered projects:
Simple Indexプロトコルの目標は、あるプロジェクトのインストールに
使うリンクの一覧をインストーラに渡すことだ。そのため、プロジェクトの
メタデータは公開されていない。そのかわりにXML-RPCを使って、
登録したプロジェクトに関する追加情報を取得できる。

\begin{verbatim}
>>> import xmlrpclib
>>> import pprint
>>> client = xmlrpclib.ServerProxy('http://pypi.python.org/pypi')
>>> client.package_releases('MPTools')
['0.1']
>>> pprint.pprint(client.release_urls('MPTools', '0.1'))
[{'comment_text': '',
'downloads': 28,
'filename': 'MPTools-0.1.tar.gz',
'has_sig': False,
'md5_digest': '6b06752d62c4bffe1fb65cd5c9b7111a',
'packagetype': 'sdist',
'python_version': 'source',
'size': 3684,
'upload_time': <DateTime '20110204T09:37:12' at f4da28>,
'url': 'http://pypi.python.org/packages/source/M/MPTools/MPTools-0.1.tar.gz'}]
>>> pprint.pprint(client.release_data('MPTools', '0.1'))
{'author': 'Tarek Ziade',
'author_email': 'tarek@mozilla.com',
'classifiers': [],
'description': 'UNKNOWN',
'download_url': 'UNKNOWN',
'home_page': 'http://bitbucket.org/tarek/mopytools',
'keywords': None,
'license': 'UNKNOWN',
'maintainer': None,
'maintainer_email': None,
'name': 'MPTools',
'package_url': 'http://pypi.python.org/pypi/MPTools',
'platform': 'UNKNOWN',
'release_url': 'http://pypi.python.org/pypi/MPTools/0.1',
'requires_python': None,
'stable_version': None,
'summary': 'Set of tools to build Mozilla Services apps',
'version': '0.1'}
\end{verbatim}

%% \noindent The issue with this approach is that some of the data that the XML-RPC
%% APIs are publishing could have been stored as static files and
%% published in the Simple Index page to simplify the work of client
%% tools.  That would also avoid the extra work PyPI has to do to handle
%% those queries.  It's fine to have non-static data like the number of
%% downloads per distribution published in a specialized web service, but
%% it does not make sense to have to use two different services to get
%% all static data about a project.
\noindent
この手法の問題は、XML-RPC APIで公開しているデータの中には、
静的ファイルとして格納してSimple Indexページで公開することもできるものがあるという点だ。
そのほうが、クライアントツールの作業量を減らせる。
また、問い合わせに対応するPyPI側としても、そうしておけば余計な手間を省ける。
公開したディストリビューションごとのダウンロード数など、変化するデータは
ウェブサービスで公開するのに適している。
しかし、プロジェクトに関する静的なデータを二種類の異なる方法で公開するのは意味がない。

\end{aosasect3}

\end{aosasect2}

%% \begin{aosasect2}{Architecture of a Python Installation}
\begin{aosasect2}{Python Installationのアーキテクチャ}

%% If you install a Python project using \code{python setup.py install},
%% \code{Distutils}---which is included in the standard library---will
%% copy the files onto your system.
Pythonのプロジェクトを\code{python setup.py install}でインストールすると、
標準ライブラリの\code{Distutils}がファイルをシステム上にコピーする。

\begin{aosaitemize}

  %% \item \emph{Python packages} and modules will land in the Python
  %% directory that is loaded when the interpreter starts: under the
  %% latest Ubuntu they will wind up in
  %% \code{/usr/local/lib/python2.6/dist\-packages/} and under Fedora in
  %% \code{/usr/local/lib/python2.6/sites-packages/}.
  \item \emph{Pythonパッケージ}やモジュールはPythonのディレクトリに配置され、
  インタプリタの起動時に読み込まれる。最新のUbuntuなら
  \code{/usr/local/lib/python2.6/dist\-packages/}だし、Fedoraなら
  \code{/usr/local/lib/python2.6/sites-packages/}だ。

  %% \item \emph{Data files} defined in a project can land anywhere
  %% on the system.
  \item プロジェクトで定義している\emph{データファイル}は
  システム上のどこにでも置ける。

  %% \item The \emph{executable script} will land in a \code{bin} directory
  %% on the system. Depending on the platform, this could be
  %% \code{/usr/local/bin} or in a bin directory specific to the Python
  %% installation.
  \item \emph{実行可能スクリプト}は、システム上の\code{bin}ディレクトリに配置する。
  その場所はプラットフォームによって異なり、\code{/usr/local/bin}
  になるかもしれないし、Pythonのインストール先にある\code{bin}ディレクトリかもしれない。

\end{aosaitemize}

%% Ever since Python~2.5, the metadata file is copied alongside the modules
%% and packages as \code{project\-version.egg-info}. For example, the
%% \code{virtualenv} project could have a
%% \code{virtualenv-1.4.9.egg\-info} file.  These metadata files can be
%% considered a database of installed projects, since it's possible to
%% iterate over them and build a list of projects with their versions.
%% However, the \code{Distutils} installer does not record the list of
%% files it installs on the system.  In other words, there is no way to
%% remove all files that were copied in the system.  This is a shame
%% since the \code{install} command has a \code{--record} option that can
%% be used to record all installed files in a text file. However, this
%% option is not used by default and \code{Distutils}' documentation
%% barely mentions it.
Python~2.5以降は、メタデータファイルもモジュールやパッケージとともにコピーされる
ようになった。ファイル名は\code{project\-version.egg-info}となる。
たとえば\code{virtualenv}プロジェクトの場合は\code{virtualenv-1.4.9.egg\-info}
のようになる。このメタデータファイルは、インストール済みのプロジェクトについてのデータベースと
考えられる。というのも、メタデータファイルを順に読んでいけば
プロジェクトとそのバージョンの一覧を作れるからである。
しかし、\code{Distutils}のインストーラはシステム上にインストールしたファイルの一覧をどこにも記録しない。
つまり、いったんコピーしたファイルをアンインストールしようと思ってもできないということになる。
情けない話だね。
\code{install}コマンドには\code{--record}っていうオプションがあって、
これを使えばインストールしたファイルの一覧をテキストファイルに残せるのに。
このオプションは標準では使われていないし、\code{Distutils}
のドキュメントにもほとんど説明がない。

\end{aosasect2}

%% \begin{aosasect2}{Setuptools, Pip and the Like}
\begin{aosasect2}{SetuptoolsやPipなど}

%% As mentioned in the introduction, some projects tried to fix some of
%% the problems with \code{Distutils}, with varying degrees of success.
最初に説明したとおり、\code{Distutils}の問題点を解決しようという
プロジェクトがいくつか存在する。それにどの程度成功したかは、プロジェクトによってさまざまだ。

%% \begin{aosasect3}{The Dependencies Issue}
\begin{aosasect3}{依存関係の問題}

%% PyPI allowed developers to publish Python projects that could include
%% several modules organized into Python packages. But at the same time,
%% projects could define module-level dependencies via \code{Require}.
%% Both ideas are reasonable, but their combination is not.
PyPIでは、複数のモジュールをひとつのPythonパッケージにまとめた
プロジェクトを公開できる。一方、
あるプロジェクトに対してモジュールレベルの依存関係を\code{Require}で定義することもできる。
どちらも合理的だが、二つの方法を組み合わせるのはよくない。「まぜるな危険」だ。

%% The right thing to do was to have project-level dependencies, which is
%% exactly what \code{Setuptools} added as a feature on the top of
%% \code{Distutils}.  It also provided a script called
%% \code{easy\_install} to automatically fetch and install dependencies
%% by looking for them on PyPI\@.  In practice, module-level dependency was
%% never really used, and people jumped on \code{Setuptools}' extensions.
%% But since these features were added in options specific to
%% \code{Setuptools}, and ignored by \code{Distutils} or PyPI,
%% \code{Setuptools} effectively created its own standard and became a
%% hack on a top of a bad design.
ほんとうにやるべきことは、プロジェクトレベルの依存関係を定義することだった。
まさにそれをやろうとしたのが\code{Setuptools}で、これは
\code{Distutils}にプロジェクトレベルの依存管理機能を追加したものである。
\code{easy\_install}というスクリプトも付属し、PyPI
経由で自動的に依存関係を取得してインストールできるようにした。
実際のところ、モジュールレベルの依存関係が使われることはなく、
人はみな\code{Setuptools}の拡張機能に飛びついた。
しかし、所詮は\code{Setuptools}でしか使えないオプションであり、
\code{Distutils}やPyPIには無視されていた。
事実上、\code{Setuptools}は独自規格を作ってしまったということになる。
もともとイケてない設計のところに無理やり手を入れて、ね。

%% \code{easy\_install} therefore needs to download the archive of the
%% project and run its \code{setup.py} script again to get the metadata
%% it needs, and it has to do this again for every dependency. The
%% dependency graph is built bit by bit after each download.
\code{easy\_install}はどうしているのかというと、
まずプロジェクトのアーカイブをダウンロードし、その\code{setup.py}
を実行してメタデータを取得する。そして、その情報を見て依存関係を取得する。
このように、依存グラフを少しずつ取得してはダウンロードをするという流れになる。

%% Even if the new metadata was accepted by PyPI and browsable online,
%% \code{easy\_install} would still need to download all archives
%% because, as said earlier, metadata published at PyPI is specific to
%% the platform that was used to upload it, which can differ from the
%% target platform.  But this ability to install a project and its
%% dependencies was good enough in 90\% of the cases and was a great
%% feature to have. So \code{Setuptools} became widely used, although it
%% still suffers from other problems:
新しいメタデータがPyPIに登録されてオンラインで見えるようになっても、
\code{easy\_install}はアーカイブ全体をダウンロードする必要がある。
というのも、先述のとおり、PyPIに公開されるメタデータは
それをアップロードしたプラットフォーム専用のものであり、
インストール先のプラットフォームとは異なる可能性があるからだ。
しかし、あるプロジェクトとその依存関係をインストールできるという機能は
たいていの場合は必要十分なものだったし、あるべき機能だった。
そのため\code{Setuptools}は広くつかわれるようになったが、
まだ問題は残っていた。

\begin{aosaitemize}

  %% \item If a dependency install fails, there is no rollback and the
  %% system can end up in a broken state.
  \item 依存パッケージのインストールに失敗したときにロールバックする手段がなく、
  システムが中途半端な状態になってしまう可能性がある。

  %% \item The dependency graph is built on the fly during installation, so
  %% if a dependency conflict is encountered the system can end up in a
  %% broken state as well.
  \item インストールを進めながらその場で徐々に依存グラフを構築していくので、
  途中で依存関係の衝突が見つかったらそこでインストールが止まってしまう。
  このときも、システムが中途半端な状態になってしまう。

\end{aosaitemize}

\end{aosasect3}

%% \begin{aosasect3}{The Uninstall Issue}
\begin{aosasect3}{アンインストールの問題}

%% \code{Setuptools} did not provide an uninstaller, even though its
%% custom metadata could have contained a file listing the installed
%% files.  \code{Pip}, on the other hand, extended \code{Setuptools}'
%% metadata to record installed files, and is therefore able to
%% uninstall.  But that's yet another custom set of metadata, which means
%% that a single Python installation may contain up to four different
%% flavours of metadata for each installed project:
\code{Setuptools}にはアンインストーラが存在しない。
インストールするファイルの一覧をカスタムメタデータとして持たせることもできるというのに。
一方\code{Pip}は、\code{Setuptools}のメタデータを拡張して
インストールしたファイルを記録できるようして、
アンインストールができるようになった。
しかし、これまたMetadataの亜種である。ということは、
Pythonのプロジェクトをインストールすると、ひとつのプロジェクトに対して
最大四種類のメタデータが存在することになってしまう。

\begin{aosaitemize}

  %% \item \code{Distutils}' \code{egg-info}, which is a single metadata
  %% file.
  \item \code{Distutils}の\code{egg-info}。これは単一のメタデータファイル。

  %% \item \code{Setuptools}' \code{egg-info}, which is a directory
  %% containing the metadata and extra \code{Setuptools} specific
  %% options.
  \item \code{Setuptools}の\code{egg-info}。これはディレクトリで、
  メタデータのほかに\code{Setuptools}専用のオプションが追加されている。

  %% \item \code{Pip}'s \code{egg-info}, which is an extended version of
  %% the previous.
  \item \code{Pip}の\code{egg-info}。これは\code{Setuptools}
  のメタデータをさらに拡張したもの。

  %% \item Whatever the hosting packaging system creates.
  \item インストール先のシステムのパッケージ管理システムが作るもの。

\end{aosaitemize}

\end{aosasect3}

\end{aosasect2}

%% \begin{aosasect2}{What About Data Files?}
\begin{aosasect2}{データファイルとは?}

%% In \code{Distutils}, data files can be installed anywhere on the
%% system.  If you define some package data files in \code{setup.py}
%% script like this:
\code{Distutils}では、データファイルはシステム上の好きなところにインストールできる。
何かのパッケージのデータファイルを\code{setup.py}で次のように定義したとしよう。

\begin{verbatim}
setup(...,
  packages=['mypkg'],
  package_dir={'mypkg': 'src/mypkg'},
  package_data={'mypkg': ['data/*.dat']},
  )
\end{verbatim}

%% \noindent then all files with the \code{.dat} extension in the \code{mypkg}
%% project will be included in the distribution and eventually installed
%% along with the Python modules in the Python installation.
\noindent
このとき、\code{mypkg}プロジェクトで拡張子が\code{.dat}のファイルがすべて
ディストリビューションに含まれ、インストール時にはPythonモジュールと同じ場所にインストールされる。

%% For data files that need to be installed outside the Python distribution, 
%% there's another option that stores files in the archive but puts them in defined
%% locations:
Pythonディストリビューションとは別の場所にインストールする必要のあるデータファイル
用には、別のオプションがある。アーカイブ内のファイルを、指定した場所に配置するためのオプションだ。

\begin{verbatim}
setup(...,
    data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                ('config', ['cfg/data.cfg']),
                ('/etc/init.d', ['init-script'])]
    )
\end{verbatim}

%% \noindent
%% This is terrible news for OS packagers for several reasons:
\noindent
これ、OSのパッケージャにとっては悪夢のように聞こえるだろう。だって、

\begin{aosaitemize}

  %% \item Data files are not part of the metadata, so packagers need to read
  %% \code{setup.py} and sometimes dive into the project's code.
  \item データファイルはメタデータに含まれないので、パッケージャは
  \code{setup.py}を読んだりプロジェクトのコードを追ったりしなければいけない。

  %% \item The developer should not be the one deciding where data files
  %% should land on a target system.
  \item 個々のシステムでデータファイルをどこに置くかなんて、開発者に決めさせることじゃないよね。

  %% \item There are no categories for these data files: images, \code{man}
  %% pages, and everything else are all treated the same way.
  \item データファイルをカテゴリ分けできない。画像も\code{man}ページもその他のデータも、
  みんな同じ扱いになってしまう。

\end{aosaitemize}

%% A packager who needs to repackage a project with such a file has no
%% choice but to patch the \code{setup.py} file so that it works as
%% expected for her platform.  To do that, she must review the code
%% and change every line that uses those files, since the developer made
%% an assumption about their location.  \code{Setuptools} and \code{Pip}
%% did not improve this.
そんなファイルを含むプロジェクトを再パッケージしようとしたパッケージャは、
\code{setup.py}ファイルに手を入れて自分のプラットフォームでも動くようにする以外の道がない。
\code{setup.py}ファイルに手を入れるには、コードを追って
データファイルを使っているすべての場所を変更しないといけない。
というのも、開発者はデータがその場所にあるという前提でコードを書いているからである。
\code{Setuptools}や\code{Pip}を使ったところで状況は変わらない。

\end{aosasect2}

\end{aosasect1}

%% \begin{aosasect1}{Improved Standards}
\begin{aosasect1}{標準規約の改良}

%% So we ended up with with a mixed up and confused packaging
%% environment, where everything is driven by a single Python module,
%% with incomplete metadata and no way to describe everything a project
%% contains.  Here's what we're doing to make things better.
というわけで、いろんなパッケージング環境が混在するややこしい状態を何とかすることにした。
ひとつのPythonモジュールですべての作業をこなしたり、メタデータが不完全だったり、
プロジェクトの内容を完全に記述する方法がなかったり、そんなのはもういやだ。
そこで私たちが何をどう改善したのかをまとめた。

%% \begin{aosasect2}{Metadata}
\begin{aosasect2}{メタデータ}

%% The first step is to fix our \code{Metadata} standard.  PEP~345
%% defines a new version that includes:
まず最初に取り組んだのは、\code{Metadata}の標準規格を修正することだった。
PEP~345で定義した新しいバージョンには以下の内容が含まれる。

\begin{aosaitemize}

  %% \item a saner way to define versions
  \item まともな方法でのバージョン定義

  %% \item project-level dependencies
  \item プロジェクトレベルの依存関係

  %% \item a static way to define platform-specific values
  \item プラットフォーム固有の値を静的に定義する方法

\end{aosaitemize}

%% \begin{aosasect3}{Version}
\begin{aosasect3}{バージョン}

%% One goal of the metadata standard is to make sure that all tools that
%% operate on Python projects are able to classify them the same
%% way. For versions, it means that every tool should be able to know
%% that ``1.1'' comes after ``1.0''. But if project have custom
%% versioning schemes, this becomes much harder.
メタデータの標準化のひとつの目標は、Pythonプロジェクトを扱うすべてのツールが
同じ方法でメタデータを扱えるようにすることだ。バージョン番号に関して言うと、
バージョン``1.1''のほうが``1.0''より新しいということを
すべてのツールがわかるようにしなければいけない。
でも、プロジェクトによってバージョンの表し方が異なると、とたんにこの目標は困難になる。

%% The only way to ensure consistent versioning is to publish a standard
%% that projects will have to follow.  The scheme we chose is a
%% classical sequence-based scheme.  As defined in PEP~386, its format
%% is:
バージョンの表し方を統一する唯一の方法は、標準規格を公開してそれに従わせることだ。
私たちが選んだのは、昔ながらの連番ベースの方式だった。
PEP~386で定義したとおり、その書式は次のようになる。

\begin{verbatim}
N.N[.N]+[{a|b|c|rc}N[.N]+][.postN][.devN]
\end{verbatim}

%% \noindent where:
\noindent
ここで、

\begin{aosaitemize}

  %% \item \emph{N} is an integer. You can use as many Ns as you want and
  %% separate them by dots, as long as there are at least two
  %% (MAJOR.MINOR).
  \item \emph{N}は整数値。
  ドットで区切って好きなだけNをつなげることができる。ただし、少なくともふたつ(MAJOR.MINOR)以上は必要。

  %% \item \emph{a}, \emph{b}, \emph{c} and \emph{rc} are \emph{alpha},
  %% \emph{beta} and \emph{release candidate} markers. They are followed
  %% by an integer. Release candidates have two markers because we wanted
  %% the scheme to be compatible with Python, which uses \emph{rc}. But
  %% we find \emph{c} simpler.
  \item \emph{a}、\emph{b}、\emph{c}および\emph{rc}は、それぞれ\emph{alpha}、\emph{beta}、\emph{リリース候補}を表すマーク。
  その後に数字を続ける。リリース候補を表すマークが\emph{c}と\emph{rc}の二種類あるのは、Python自身が\emph{rc}
  を使っていることに合わせたものである。私たちは、\emph{c}のほうがよりシンプルだと考える。

  %% \item \emph{dev} followed by a number is a dev marker.
  \item \emph{dev}の後に数字を続けて、開発版を表す。

  %% \item \emph{post} followed by a number is a post-release marker.
  \item \emph{post}の後に数字を続けて、ポストリリース版を表す。

\end{aosaitemize}

%% \noindent
%% Depending on the project release process, dev or post markers can be used for
%% all intermediate versions between two final releases. Most process use
%% dev markers.
\noindent
プロジェクトのリリース手順によっては、最終版の二つのリリースの間にある中間バージョンに対して
devあるいはpostを使える。たいていのプロジェクトではdevを使っている。

\pagebreak

%% Following this scheme, PEP~386 defines a strict ordering:
この方針に則って、PEP~386では厳密な順番を定義している。

\begin{aosaitemize}

  %% \item alpha {\textless} beta {\textless} rc {\textless} final
  \item alpha {\textless} beta {\textless} rc {\textless} final

  %% \item dev {\textless} non-dev {\textless} post, where non-dev can be a alpha, beta,
  %% rc or final
  \item dev {\textless} non-dev {\textless} post、ここでnon-devとはalpha、beta、rcあるいはfinalを指す

\end{aosaitemize}

%% \noindent
%% Here's a full ordering example:
\noindent
例を示そう。

\begin{verbatim}
1.0a1 < 1.0a2.dev456 < 1.0a2 < 1.0a2.1.dev456
  < 1.0a2.1 < 1.0b1.dev456 < 1.0b2 < 1.0b2.post345
    < 1.0c1.dev456 < 1.0c1 < 1.0.dev456 < 1.0
      < 1.0.post456.dev34 < 1.0.post456
\end{verbatim}

%% \noindent
%% The goal of this scheme is to make it easy for other packaging systems
%% to translate Python projects' versions into their own schemes.  PyPI
%% now rejects any projects that upload PEP~345 metadata with version numbers
%% that don't follow PEP~386.
\noindent
この方針の目標は、他のパッケージングシステムがPythonのプロジェクトのバージョンを自分たちの管理する方式に変換しやすくすることだ。
今やPyPIは、PEP~345のメタデータをアップロードしたときに
PEP~386に従わないバージョン番号をつけているプロジェクトを拒否するようになった。

\end{aosasect3}

%% \begin{aosasect3}{Dependencies}
\begin{aosasect3}{依存関係}

%% PEP~345 defines three new fields that replace PEP~314 \code{Requires},
%% \code{Provides}, and \code{Obsoletes}. Those fields are
%% \code{Requires-Dist}, \code{Provides-Dist}, and \code{Obsoletes-Dist},
%% and can be used multiple times in the metadata.
PEP~345では新たに三種類のフィールドを定義した。PEP~314の\code{Requires}、\code{Provides}そして\code{Obsoletes}
に取って代わるものだ。その名は\code{Requires-Dist}、\code{Provides-Dist}そして
\code{Obsoletes-Dist}で、メタデータの中で複数回使える。

%% For \code{Requires-Dist}, each entry contains a string naming some
%% other \code{Distutils} project required by this distribution.  The
%% format of a requirement string is identical to that of a
%% \code{Distutils} project name (e.g., as found in the \code{Name} field)
%% optionally followed by a version declaration within parentheses.
%% These \code{Distutils} project names should correspond to names as
%% found at PyPI, and version declarations must follow the rules
%% described in PEP~386. Some example are:
\code{Requires-Dist}では、このディストリビューションが必要とする他の\code{Distutils}
プロジェクトの名前を文字列で指定する。文字列の書式は\code{Distutils}のプロジェクト名
(つまり\code{Name}フィールドにあるもの)と同じで、その後に続けて括弧内にバージョンを宣言できる。
\code{Distutils}のプロジェクト名はPyPIで探すときの名前に対応し、バージョンの宣言方法は
PEP~386のルールに従う。いくつか例を示す。

\begin{verbatim}
Requires-Dist: pkginfo
Requires-Dist: PasteDeploy
Requires-Dist: zope.interface (>3.5.0)
\end{verbatim}

%% \noindent \code{Provides-Dist} is used to define extra names contained in the
%% project.  It's useful when a project wants to merge with another
%% project. For example the ZODB project can include the
%% \code{transaction} project and state:
\noindent
\code{Provides-Dist}は、このプロジェクトに含まれる追加の名前を定義する。
あるプロジェクトを別のプロジェクトと混ぜたい場合に有用だ。
たとえばZODBプロジェクトには\code{transaction}プロジェクトを含めることができ、
その場合は次のように宣言する。

\begin{verbatim}
Provides-Dist: transaction
\end{verbatim}

%% \noindent \code{Obsoletes-Dist} is useful to mark another project as an obsolete
%% version:
\noindent
\code{Obsoletes-Dist}は、別のプロジェクトを非推奨扱いにできる。

\begin{verbatim}
Obsoletes-Dist: OldName
\end{verbatim}

\end{aosasect3}

%% \begin{aosasect3}{Environment Markers}
\begin{aosasect3}{環境マーカー}

%% An environment marker is a marker that can be added at the end of a
%% field after a semicolon to add a condition about the execution
%% environment.  Some examples are:
環境マーカーは、フィールドの最後にセミコロンに続けて追加するマークで、
実行環境に関する条件を指定する。いくつか例を示す。

\begin{verbatim}
Requires-Dist: pywin32 (>1.0); sys.platform == 'win32'
Obsoletes-Dist: pywin31; sys.platform == 'win32'
Requires-Dist: foo (1,!=1.3); platform.machine == 'i386'
Requires-Dist: bar; python_version == '2.4' or python_version == '2.5'
Requires-External: libxslt; 'linux' in sys.platform
\end{verbatim}

%% The micro-language for environment markers is deliberately kept simple
%% enough for non-Python programmers to understand: it compares strings
%% with the \code{==} and \code{in} operators (and their opposites), and
%% allows the usual Boolean combinations.  The fields in PEP~345 that can
%% use this marker are:
環境マーカー用のマイクロ言語は、意図的にシンプルにしている。Pythonプログラマー
以外にも理解してもらえるようにするためだ。文字列は\code{==}演算子と\code{in}
演算子(そしてそれぞれの逆の演算子)で比較し、通常の論理演算子が使える。
PEP~345のフィールドの中でこのマーカーが使えるものは、次のとおりである。

\begin{aosaitemize}
  \item \code{Requires-Python}
  \item \code{Requires-External}
  \item \code{Requires-Dist}
  \item \code{Provides-Dist}
  \item \code{Obsoletes-Dist}
  \item \code{Classifier}
\end{aosaitemize}

\end{aosasect3}

\end{aosasect2}

%% \begin{aosasect2}{What's Installed?}
\begin{aosasect2}{何がインストールされたのか?}

%% Having a single installation format shared among all Python tools is
%% mandatory for interoperability. If we want Installer A to detect that
%% Installer B has previously installed project Foo, they both need to
%% share and update the same database of installed projects.
単一のインストール形式を、すべてのPythonツール群で共有する。
相互運用性を確保するためには、これが必須である。
たとえば、インストーラーBが以前にプロジェクトFooをインストールしたという事実を
インストーラーAで検出できるようにしたければ、インストールされたプロジェクトの
情報を同じデータベースで共有しなければいけない。

%% Of course, users should ideally use a single installer in their
%% system, but they may want to switch to a newer installer that has
%% specific features. For instance, Mac OS X ships \code{Setuptools}, so
%% users automatically have the \code{easy\_install} script. If they
%% want to switch to a newer tool, they will need it to be backward
%% compatible with the previous one.
もちろん、あれこれ使わずにひとつのインストーラーで揃えるのが理想ではある。
でも、目新しい機能を搭載した新しいインストーラーが登場したら、つい使ってしまいたくなるものだ。
たとえば、Mac OS Xには標準で\code{Setuptools}が含まれているので、ユーザーは
自動的に\code{easy\_install}スクリプトを使えるようになる。
ユーザーが新しいツールを使おうと思ったら、以前のツールとの互換性が必要となる。

%% Another problem when using a Python installer on a platform that has a
%% packaging system like RPM is that there is no way to inform the system
%% that a project is being installed. What's worse, even if the Python
%% installer could somehow ping the central packaging system, we would
%% need to have a mapping between the Python metadata and the system
%% metadata. The name of the project, for instance, may be different for
%% each. That can occur for several reasons. The most common one is 
%% a conflict name: another project outside the Python land already uses
%% the same name for the RPM. Another cause is that the name used include
%% a \code{python} prefix that breaks the convention of the platform.
%% For example, if you name your project \code{foo-python}, there are high
%% chances that the Fedora RPM will be called \code{python-foo}.
別の問題もある。RPMなどのパッケージ管理システムを持つプラットフォームで
Pythonインストーラーを使ったときに、何かのプロジェクトがインストールされたことを
システム側に伝える方法がないのだ。さらに悪いことに、
たとえPythonインストーラー側から何らかの方法でシステムのパッケージ管理システム
に通知できたとしても、Pythonのメタデータとシステムのメタデータの間で
マッピングが必要となる。たとえばプロジェクト名ひとつとっても
お互い違うこともある。その理由はいくつかあって、
いちばんありがちなのは名前の衝突だ。Python界とは無関係の別のプロジェクトが、
そのプロジェクトと同じ名前のRPMを作っている場合などである。
それ以外にあり得るのは、\code{python}のプレフィックスを含む名前が
プラットフォーム側の命名規約と衝突してしまうという例だ。
たとえば\code{foo-python}というプロジェクトを作ったとしよう。
FedoraのRPMなら、高い確率でそれは\code{python-foo}という名前になるだろう。

%% One way to avoid this problem is to leave the global Python
%% installation alone, managed by the central packaging system, and work
%% in an isolated environment.  Tools like \code{Virtualenv} allows this.
この問題を回避する方法のひとつは、システム全体で使うPythonの環境は
システムのパッケージングシステムにまかせておいて、それとは別に隔離した環境で作業することだ。
\code{Virtualenv}のようなツールを使えば、それができる。

%% In any case, we do need to have a single installation format in Python
%% because interoperability is also a concern for other packaging systems
%% when they install themselves Python projects.  Once a third-party 
%% packaging system has registered a newly installed project in its 
%% own database on the system, it needs to generate the right metadata 
%% for the Python installaton itself, so projects appear to be installed 
%% to Python installers or any APIs that query the Python installation.
いずれにせよ、Pythonの世界でのインストーラーのフォーマットを統一する必要がある。
だって、他のパッケージングシステムがPythonのプロジェクトをインストールするときにも、
相互運用性は重要になるからだ。サードパーティのパッケージングシステムが
新しいPythonプロジェクトをインストールして自前のデータベースに登録したら、
何とかしてPython自身に正しいメタデータを伝える必要がある。
そうすれば、Pythonインストーラー(あるいはPythonプロジェクトのインストール状態を
調べる何らかのAPI)からもそのプロジェクトがインストールされたことがわかるようになる。

%% The metadata mapping issue can be addressed in that case: since an RPM
%% knows which Python projects it wraps, it can generate the proper
%% Python-level metadata. For instance, it knows that
%% \code{python26-webob} is called \code{WebOb} in the PyPI ecosystem.
メタデータのマッピングができれば、こんなときにも対応できる。
RPMは自身が管理するPythonプロジェクトを知っているので、
そこから適切なPythonメタデータを生成できるようになるのだ。
たとえば、\code{python26-webob}はPyPIの世界では\code{WebOb}と呼ばれているといったマッピングだ。

%% Back to our standard: PEP~376 defines a standard for installed
%% packages whose format is quite similar to those used by
%% \code{Setuptools} and \code{Pip}.  This structure is a directory with
%% a \code{dist-info} extension that contains:
さて、標準化の話題に戻る。PEP~376では、インストール済みパッケージの標準フォーマットを定義した。
\code{Setuptools}や\code{Pip}で使っているフォーマットと似た形式である。
拡張子\code{dist-info}のディレクトリに、このような内容を含める。

\begin{aosaitemize}

  %% \item \code{METADATA}: the metadata, as described in PEP~345, PEP~314
  %% and PEP~241.
  \item \code{METADATA}: PEP~345、PEP~314およびPEP~241で記されたメタデータ。

  %% \item \code{RECORD}: the list of installed files in a csv-like format.
  \item \code{RECORD}: インストールされたファイルの一覧をcsv風の書式で表したもの。

  %% \item \code{INSTALLER}: the name of the tool used to install the
  %% project.
  \item \code{INSTALLER}: このプロジェクトをインストールするときに使ったツールの名前。

  %% \item \code{REQUESTED}: the presence of this file indicates that the
  %% project installation was explicitly requested (i.e., not installed
  %% as a dependency).
  \item \code{REQUESTED}: このファイルが存在すれば、そのプロジェクトは明示的にインストールされたものだということを表す
             (依存関係を満たすために自動的にインストールされた場合は、このファイルは存在しない)。

\end{aosaitemize}

%% \noindent
%% Once all tools out there understand this format, we'll be able to
%% manage projects in Python without depending on a particular installer
%% and its features.  Also, since PEP~376 defines the metadata as a
%% directory, it will be easy to add new files to extend it.  As a matter
%% of fact, a new metadata file called \code{RESOURCES}, described in the
%% next section, might be added in a near future without modifying
%% PEP~376. Eventually, if this new file turns out to be useful for all
%% tools, it will be added to the PEP.
\noindent
すべてのツールがこのフォーマットに対応するようになれば、
特定のインストーラーやその機能に頼らずにPythonのプロジェクトを管理できるようになる。
また、PEP~376ではメタデータをディレクトリとして定義しているので、
メタデータを拡張するときにも単に新しいファイルを追加するだけで済む。
実際、次のセクションで解説する新たなメタデータファイル\code{RESOURCES}
は、近い将来に追加される予定だ。これを追加してもPEP~376には手を加えない。
最終的にこのファイルがすべてのツールにとって有用だとわかれば、
そのときにPEPに追加されることだろう。

\end{aosasect2}

%% \begin{aosasect2}{Architecture of Data Files}
\begin{aosasect2}{データファイルのアーキテクチャ}

%% As described earlier, we need to let the packager decide where to put
%% data files during installation without breaking the developer's
%% code. At the same time, the developer must be able to work with data
%% files without having to worry about their location.  Our solution is
%% the usual one: indirection.
先述の通り、インストール時のデータファイルの置き場所はパッケージャーが自由に決められるようにする必要がある。
そして、どこに置いても開発者の書いたコードが動くようにもしなければいけない。
同時に、開発者も、データファイルの置き場所がどこであるかを意識せずに作業できるようでなければいけない。
そこで私たちがどうしたか。よくある手段、つまり間接参照だ。

%% \begin{aosasect3}{Using Data Files}
\begin{aosasect3}{データファイルの利用}

%% Suppose your \code{MPTools} application needs to work with a
%% configuration file.  The developer will put that file in a Python
%% package and use \code{\_\_file\_\_} to reach it:
\code{MPTools}アプリケーションで設定ファイルが必要になったとする。開発者は設定ファイルをPython
パッケージの中に置き、\code{\_\_file\_\_}で参照しようとするだろう。

\begin{verbatim}
import os

here = os.path.dirname(__file__)
cfg = open(os.path.join(here, 'config', 'mopy.cfg'))
\end{verbatim}

%% \noindent This implies that configuration files are installed like code, and
%% that the developer \emph{must} place it alongside her code: in this
%% example, in a subdirectory called \code{config}.
\noindent
これは、設定ファイルがコードと同じようにインストールされており、かつ開発者が
設定ファイルをコードと同じ場所に\emph{置かないといけない}ということを前提としている。
この例では\code{config}というディレクトリがあるものと見なしている。

%% The new architecture of data files we have designed
%% uses the project tree as the root
%% of all files, and allows access to any file in the tree, whether it is
%% located in a Python package or a simple directory.  This allowed
%% developers to create a dedicated directory for data files and access
%% them using \code{pkgutil.open}:
データファイルの新たなアーキテクチャを設計する際には、このように考えた。
プロジェクトツリーをすべてのファイルのルートとして使い、
ツリー内のすべてのファイルに対して、
Pythonパッケージであっても単純なディレクトリであってもアクセスできるようにした。
これで、開発者はデータファイル専用のディレクトリを作れるようになり、そこに\code{pkgutil.open}
でアクセスできるようになったのだ。

\begin{verbatim}
import os
import pkgutil

# Open the file located in config/mopy.cfg in the MPTools project
cfg = pkgutil.open('MPTools', 'config/mopy.cfg')
\end{verbatim}

%% \noindent \code{pkgutil.open} looks for the project metadata and see if it
%% contains a \code{RESOURCES} file. This is a simple map of files to
%% locations that the system may contain:
\noindent
\code{pkgutil.open}は、プロジェクトのメタデータを読んで\code{RESOURCES}ファイルが含まれているかどうかを調べる。
このファイルは、システムに含まれるファイルの場所をまとめたシンプルなマップだ。

\begin{verbatim}
config/mopy.cfg {confdir}/{distribution.name}
\end{verbatim}

%% \noindent Here the \code{{confdir}} variable points to the
%% system's configuration directory, and \code{{distribution.name}}
%% contains the name of the Python project as found in the metadata.
\noindent
ここで、\code{{confdir}}が指すのはシステムの設定ディレクトリであり、
\code{{distribution.name}}に含まれるのはメタデータに書かれたPythonプロジェクト名である。

%% \aosafigure[300pt]{../images/packaging/find-file.eps}{Finding a File}{fig.packaging.findfile}
\aosafigure[300pt]{../images/packaging/find-file.eps}{ファイルを探す流れ}{fig.packaging.findfile}

%% As long as this \code{RESOURCES} metadata file is created at
%% installation time, the API will find the location of \code{mopy.cfg}
%% for the developer.  And since \code{config/mopy.cfg} is the path
%% relative to the project tree, it means that we can also offer a
%% development mode where the metadata for the project are generated
%% in-place and added in the lookup paths for \code{pkgutil}.
インストール時に\code{RESOURCES}ファイルを作っておきさえすれば、
このAPIが\code{mopy.cfg}の場所を見つけてくれるようになる。
また、\code{config/mopy.cfg}はプロジェクトのツリーからの相対パスなので、
開発モードも用意できる。開発モードのときにはプロジェクトのメタデータをその場で生成し、
\code{pkgutil}用の検索パスを追加すればよい。

\end{aosasect3}

%% \begin{aosasect3}{Declaring Data Files}
\begin{aosasect3}{データファイルの宣言}

%% In practice, a project can define where data files should land by
%% defining a mapper in their \code{setup.cfg} file.  A mapper is a
%% list of \code{(glob-style pattern, target)} tuples. Each pattern
%% points to one of several files in the project tree, while the target
%% is an installation path that may contain variables in brackets.  For
%% example, \code{MPTools}'s \code{setup.cfg} could look like this:
実際には、データファイルをどこに配置するのかはプロジェクトで定義できる。
\code{setup.cfg}ファイルでマッパーを定義すればよい。
マッパーというのは、\code{(glob-style pattern, target)}からなるタプルのリストである。
各パターンがプロジェクトツリー内のいずれかのファイルを指し、
ターゲットにはインストール先のパスを指定する。このパスには、ブラケットで囲んだ変数を含めることができる。
たとえば\code{MPTools}の\code{setup.cfg}は次のようになる。

\begin{verbatim}
[files]
resources =
        config/mopy.cfg {confdir}/{application.name}/
        images/*.jpg    {datadir}/{application.name}/
\end{verbatim}

%% \noindent
%% The \code{sysconfig} module will provide and document a specific list
%% of variables that can be used, and default values for each platform.
%% For example \code{{confdir}} is \code{/etc} on Linux.  Installers can
%% therefore use this mapper in conjunction with \code{sysconfig} at
%% installation time to know where the files should be placed.
%% Eventually, they will generate the \code{RESOURCES} file mentioned
%% earlier in the installed metadata so \code{pkgutil} can find back the
%% files.
\noindent
\code{sysconfig}モジュールが、ここで使える変数の一覧やそのドキュメントを提供しており、
各プラットフォームでのデフォルト値も設定している。
たとえば、Linux上での\code{{confdir}}のデフォルトは\code{/etc}となる。
インストーラーは、このマッパーと\code{sysconfig}を組み合わせれば
ファイルの配置先を知ることができる。
最終的には先述の\code{RESOURCES}ファイルを生成してメタデータに含めるので、
\code{pkgutil}が後からデータファイルを見つけられるようになる。

%% \aosafigure[300pt]{../images/packaging/installer.eps}{Installer}{fig.packaging.installer}
\aosafigure[300pt]{../images/packaging/installer.eps}{インストーラー}{fig.packaging.installer}

\end{aosasect3}

\end{aosasect2}

%% \begin{aosasect2}{PyPI Improvements}
\begin{aosasect2}{PyPIの改良}

%% I said earlier that PyPI was effectively a single point of
%% failure. PEP~380 addresses this problem by defining a mirroring
%% protocol so that users can fall back to alternative servers when PyPI
%% is down. The goal is to allow members of the community to run mirrors
%% around the world.
先述のとおり、PyPIは事実上の単一障害点だった。
PEP~380では、この問題に対応するためにミラーリングプロトコルを導入し、
PyPIが落ちているときに他の代替サーバーにフォールバックできるようにした。
その狙いは、コミュニティのメンバーが世界中でミラーを稼働させられるようにすることだ。

%% \aosafigure[250pt]{../images/packaging/mirroring.eps}{Mirroring}{fig.packaging.mirroring}
\aosafigure[250pt]{../images/packaging/mirroring.eps}{ミラーリング}{fig.packaging.mirroring}

%% The mirror list is provided as a list of host names of the form
%% \code{X.pypi.python.org}, where \code{X} is in the sequence
%% \code{a,b,c,...,aa,ab,...}.  \code{a.pypi.python.org} is the master
%% server and mirrors start with b. A CNAME record
%% \code{last.pypi.python.org} points to the last host name so clients
%% that are using PyPI can get the list of the mirrors by looking at the
%% CNAME.
ミラーリストの形式は、\code{X.pypi.python.org}形式のホスト名のリストとなる。
ここで\code{X}は、\code{a,b,c,...,aa,ab,...}のようなシーケンスである。
\code{a.pypi.python.org}がマスターサーバーで、ミラーはbから始まる。
CNAMEレコード\code{last.pypi.python.org}は最後のホスト名を指しているので、
PyPIを使うクライアントは、このCNAMEを見ればミラー一覧を取得できる。

%% For example, this call tells use that the last mirror is
%% \code{h.pypi.python.org}, meaning that PyPI currently has 6 mirrors (b
%% through h):
たとえば次の結果を見ると、最後のミラーが\code{h.pypi.python.org}
であることがわかる。つまり、この時点でPyPIには六つのミラー
(bからh)があるということだ。

\begin{verbatim}
>>> import socket
>>> socket.gethostbyname_ex('last.pypi.python.org')[0]
'h.pypi.python.org'
\end{verbatim}

%% \noindent Potentially, this protocol allows clients to redirect requests to the
%% nearest mirror by localizing the mirrors by their IPs, and also fall
%% back to the next mirror if a mirror or the master server is down.  The
%% mirroring protocol itself is more complex than a simple rsync because
%% we wanted to keep downloads statistics accurate and provide minimal
%% security.
\noindent
将来的に、このプロトコルを使ってクライアントから一番近いミラーへとリクエストをリダイレクト
できるようにする可能性もある。IPアドレスを元に近場のミラーを探し、
もしそのミラーあるいはマスターがダウンしていれば次のミラーを探すといった流れだ。
ミラーリングプロトコル自体は単純なrsyncよりは複雑なものだ。
というのも、ダウンロードの統計情報を正確に記録したり
最低限のセキュリティを確保したりしたかったからである。

%% \begin{aosasect3}{Synchronization}
\begin{aosasect3}{同期処理}

%% Mirrors must reduce the amount of data transferred between the central
%% server and the mirror. To achieve that, they \emph{must} use the
%% \code{changelog} PyPI XML-RPC call, and only refetch the packages that
%% have been changed since the last time.  For each package P, they
%% \emph{must} copy documents \code{/simple/P/} and \code{/serversig/P}.
ミラーリング環境では、中央サーバーとミラーとの間でのデータ転送量を軽減する必要がある。
そのため、ミラーではPyPIのXML-RPCコール\code{changelog}を使わないといけない。
そして、前回以降で変更があったパッケージだけを再取得するのだ。
ひとつのパッケージPに対してドキュメント\code{/simple/P/}および\code{/serversig/P}もコピーする必要がある。

%% If a package is deleted on the central server, they \emph{must} delete
%% the package and all associated files. To detect modification of
%% package files, they may cache the file's ETag, and may request
%% skipping it using the \code{If-None-Match} header.  Once the
%% synchronization is over, the mirror changes its \code{/last-modified}
%% to the current date.
パッケージが中央サーバーから削除されたら、
そのパッケージおよびすべての関連ファイルを削除する必要がある。
パッケージの内容が変更されたかどうかを検出するために、ファイルのETagをキャッシュする。
そして、\code{If-None-Match}ヘッダーを使ってリクエストをスキップすることもある。
同期が完了したら、ミラーは自身の\code{/last-modified}を現在日時に設定する。

\end{aosasect3}

%% \begin{aosasect3}{Statistics Propagation}
\begin{aosasect3}{統計情報の伝搬}

%% When you download a release from any of the mirrors, the protocol
%% ensures that the download hit is transmitted to the master PyPI
%% server, then to other mirrors.  Doing this ensures that people or
%% tools browsing PyPI to find out how many times a release was downloaded
%% will get a value summed across all mirrors.
どこかのミラーから何かのリリースをダウンロードすると、ミラーリングプロトコルは
ダウンロードがあったことをPyPIマスターサーバーに送信し、そしてそれが他のミラーにも伝搬する。
こうすることで、PyPIを見れば、あるリリースが全部で何回ダウンロードされたのかという情報を
全ミラーの合計値で取得できるようになる。

%% Statistics are grouped into daily and weekly CSV files in the
%% \code{stats} directory at the central PyPI itself.  Each mirror needs
%% to provide a \code{local-stats} directory that contains its own
%% statistics. Each file provides the number of downloads for each
%% archive, grouped by use agents.  The central server visits mirrors
%% daily to collect those statistics, and merge them back into the global
%% \code{stats} directory, so each mirror must keep \code{/local-stats}
%% up-to-date at least once a day.
統計情報は日次および週次でCSVファイルにまとめられ、
PyPIの中央サーバーの\code{stats}ディレクトリに置かれている。
各ミラーサーバーは、\code{local-stats}というディレクトリを用意して
自分のサーバーに関する統計情報を置かなければいけない。
各ファイルに含まれる内容はアーカイブごとのダウンロード回数で、
利用したエージェントごとにそれをまとめている。
中央サーバーは各ミラーの統計情報を日に一度収集し、それをグローバルな
\code{stats}ディレクトリに取りまとめる。
つまり、ミラー側は少なくとも日に一度のペースで\code{/local-stats}
を最新に更新しておく必要がある。

\end{aosasect3}

%% \begin{aosasect3}{Mirror Authenticity}
\begin{aosasect3}{信頼性のミラー}

%% With any distributed mirroring system, clients may want to verify that
%% the mirrored copies are authentic.  Some of the possible threats
%% include:
あらゆる分散ミラーリングシステムに共通する問題がある。
クライアント側から、ミラーの内容が本物かどうかを調べたくなるということだ。
分散ミラーリングシステムで考えられる脅威には、このようなものがある。

\begin{aosaitemize}

  %% \item the central index may be compromised
  \item 中央インデックスが攻撃を受ける

  %% \item the mirrors might be tampered with
  \item ミラーが改ざんされる

  %% \item a man-in-the-middle attack between the central index and the end
  %% user, or between a mirror and the end user
  \item 中央インデックスとエンドユーザー、あるいはミラーとエンドユーザーの間での中間者攻撃

\end{aosaitemize}

%% \noindent
%% To detect the first attack, package authors need to sign their
%% packages using PGP keys, so that users can verify that the package
%% comes from the author they trust.  The mirroring protocol itself only
%% addresses the second threat, though some attempt is made to detect
%% man-in-the-middle attacks.
\noindent
最初のパターンの攻撃を検出するには、パッケージの作者がPGP鍵で
パッケージに署名する必要がある。そうすれば、そのパッケージが
本当に作者の作ったものであるかをユーザーが検証できるようになる。
ミラーリングプロトコルで対応できるのは二番目の脅威だけであるが、
中間者攻撃に対応するための試みもとられている。

%% The central index provides a DSA key at the URL \code{/serverkey}, in
%% the PEM format as generated by \code{openssl dsa -pubout}\footnote{I.e.,
%% RFC 3280 SubjectPublicKeyInfo,
%% with the algorithm 1.3.14.3.2.12.}. This URL must not be mirrored,
%% and clients must fetch the official \code{serverkey} from PyPI
%% directly, or use the copy that came with the PyPI client
%% software. Mirrors should still download the key so that they can
%% detect a key rollover.
中央インデックスはURL \code{/serverkey}でDSA鍵を提供していつ。
これはPEMフォーマットで、\code{openssl dsa -pubout}
\footnote{RFC 3280 SubjectPublicKeyInfo, with the algorithm 1.3.14.3.2.12.}
で生成したものだ。このURLは決してミラーしてはいけない。クライアントは、
PyPIから直接取得した公式の\code{serverkey}か、PyPIクライアントソフトウェアに
付属するそのコピーを利用する。ミラー側は、このキーをダウンロードしておかなければいけない。
これを使って、キーの改変を検出する。

%% For each package, a mirrored signature is provided at
%% \code{/serversig/package}.  This is the DSA signature of the parallel
%% URL \code{/simple/package}, in DER form, using SHA-1 with
%% DSA\footnote{I.e., as a RFC 3279 Dsa-Sig-Value, created by algorithm
%%   1.2.840.10040.4.3.}.
各パッケージについて、ミラーされたシグネチャを\code{/serversig/package}で提供する。
これは、対応するURL \code{/simple/package}のDSAシグネチャをDER形式で表したもので、
SHA-1とDSA\footnote{RFC 3279 Dsa-Sig-Value, created by algorithm   1.2.840.10040.4.3.}
を使っている。

%% Clients using a mirror need to perform the following steps to verify a
%% package:
ミラーを使うクライアントは、次の手順でパッケージを検証しなければいけない。

\begin{enumerate}

  %% \item Download the \code{/simple} page, and compute its SHA-1 hash.
  \item \code{/simple}をダウンロードし、そのSHA-1ハッシュを計算する。

  %% \item Compute the DSA signature of that hash.
  \item そのハッシュのDSAシグネチャを計算する。

  %% \item Download the corresponding \code{/serversig}, and compare it
  %% byte for byte with the value computed in step 2.
  \item 対応する\code{/serversig}をダウンロードし、先ほど計算した値とバイト単位で比較する。

  %% \item Compute and verify (against the \code{/simple} page) the MD5
  %% hashes of all files they download from the mirror.
  \item ミラーからダウンロードしたすべてのファイルについて、そのMD5ハッシュを計算して
  (\code{/simple}ページに対して)検証する。

\end{enumerate}

%% Verification is not needed when downloading from central index, and
%% clients should not do it to reduce the computation overhead.
中央インデックスからダウンロードする場合は検証は不要なので、
計算のオーバーヘッドを減らすためにも、そんな場合はむしろ検証すべきではない。

%% About once a year, the key will be replaced with a new one. Mirrors
%% will have to re-fetch all \code{/serversig} pages. Clients using
%% mirrors need to find a trusted copy of the new server key. One way to
%% obtain one is to download it from
%% \url{https://pypi.python.org/serverkey}.  To detect man-in-the-middle
%% attacks, clients need to verify the SSL server certificate, which will
%% be signed by the CACert authority.
ほぼ一年に一度の頻度で、キーを新しいものと交換する。そのときは、
各ミラーが\code{/serversig}ページをすべて取り直す必要がある。
ミラーを使うクライアントも、新しいキーの信頼できるコピーを取得しないといけない。
キーを取得する方法のひとつは、\url{https://pypi.python.org/serverkey}からのダウンロードだ。
中間者攻撃を検出するために、クライアントはSSLサーバー証明書を検証しなければいけない。
この証明書は認証局により署名されている。

\end{aosasect3}

\end{aosasect2}

\end{aosasect1}

%% \begin{aosasect1}{Implementation Details}
\begin{aosasect1}{実装の詳細}

%% The implementation of most of the improvements described in the previous
%% section are taking place in \code{Distutils2}.  The \code{setup.py}
%% file is not used anymore, and a project is completely described in
%% \code{setup.cfg}, a static \code{.ini}-like file.  By doing this, we
%% make it easier for packagers to change the behavior of a project
%% installation without having to deal with Python code.  Here's an
%% example of such a file:
これまでに説明してきた改良のほとんどの実装は、\code{Distutils2}で行った。
\code{setup.py}ファイルを使うのはやめて、プロジェクトの設定を完全に\code{setup.cfg}
に移行した。これは、\code{.ini}風の静的なファイルである。
こうすることで、パッケージャがプロジェクトのインストール方法を変更するときにも
Pythonのコードをいじる必要がなくなった。\code{setup.cfg}の例を次に示す。

\begin{verbatim}
[metadata]
name = MPTools
version = 0.1
author = Tarek Ziade
author-email = tarek@mozilla.com
summary = Set of tools to build Mozilla Services apps
description-file = README
home-page = http://bitbucket.org/tarek/pypi2rpm
project-url: Repository, http://hg.mozilla.org/services/server-devtools
classifier = Development Status :: 3 - Alpha
    License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)
\end{verbatim}

\begin{verbatim}
[files]
packages =
        mopytools
        mopytools.tests

extra_files =
        setup.py
        README
        build.py
        _build.py

resources =
    etc/mopytools.cfg {confdir}/mopytools
\end{verbatim}

%% \noindent \code{Distutils2} use this configuration file to:
\noindent
\code{Distutils2}は、この設定ファイルを使って次のことを行う。

\begin{aosaitemize}

  %% \item generate \code{META-1.2} metadata files that can be used for various
  %% actions, like registering at PyPI.
  \item メタデータファイル\code{META-1.2}の生成。
  このファイルは、PyPIへの登録などのさまざまな作業に使える。

  %% \item run any package management command, like \code{sdist}.
  \item 任意のパッケージ管理コマンド(\code{sdist}など)の実行。

  %% \item install a \code{Distutils2}-based project.
  \item \code{Distutils2}ベースのプロジェクトのインストール。

\end{aosaitemize}

%% \noindent
%% \code{Distutils2} also implements \code{VERSION} via its \code{version}
%% module.
\noindent
\code{Distutils2}では\code{VERSION}も実装している。
これは\code{version}モジュールを利用したものだ。

%% The \code{INSTALL-DB} implementation will find its way to the standard library
%% in Python 3.3 and will be in the \code{pkgutil} module. In the
%% interim, a version of this module exists in \code{Distutils2} for
%% immediate use.  The provided APIs will let us browse an installation
%% and know exactly what's installed.
\code{INSTALL-DB}の実装はPython 3.3で標準ライブラリ入りする見込みで、
\code{pkgutil}モジュールに入ることになる。今のところは\code{Distutils2}
に入っているが、暫定的なものである。ここで提供するAPIを使えば、
インストールされたものを閲覧して何がインストールされたのかを知ることができる。

%% These APIs are the basis for some neat \code{Distutils2} features:
これらのAPIを使って、\code{Distutils2}のこんなイケてる機能を提供している。

\begin{aosaitemize}
  %% \item installer/uninstaller
  \item インストーラー/アンインストーラー
  %% \item dependency graph view of installed projects
  \item インストールされたプロジェクトに関する依存グラフの表示
\end{aosaitemize}

\end{aosasect1}

%% \begin{aosasect1}{Lessons learned}
\begin{aosasect1}{教訓}

%% \begin{aosasect2}{It's All About PEPs}
\begin{aosasect2}{PEPこそがすべて}

%% Changing an architecture as wide and complex as Python packaging 
%% needs to be carefully done by changing standards through a
%% PEP process. And changing or adding a new PEP takes in my
%% experience around a year.
Pythonパッケージングのように大規模で複雑なアーキテクチャを変更するには、
細心の注意を要する。PEPプロセスを経て、標準規約を変更することになる。
経験上、PEPを変更したり新たに追加したりするには一年はかかる。

%% One mistake the community made along the way was to deliver tools 
%% that solved some issues by extending the Metadata and the way Python 
%% applications were installed without trying to change the impacted 
%% PEPs.
これまでにコミュニティが犯した過ちのひとつが、
既存のMetadataを拡張して問題を解決しようとしたことだ。
Pythonのアプリケーションをインストールする方法を、
PEPを変更することなしに変えてしまったのだ。

%% In other words, depending on the tool you used, the standard library
%% \code{Distutils} or \code{Setuptools}, applications were installed
%% differently. The problems were solved for one part of the community 
%% that used these new tools, but added more problems for the rest of 
%% the world.
%% OS Packagers for instance, had to face several Python standards:
%% the official documented standard and the de-facto standard imposed by 
%% \code{Setuptools}.
言い換えると、使っているツールが何かによって、
標準ライブラリ\code{Distutils}あるいは\code{Setuptools}のどちらを使っているかによって、
アプリケーションのインストール方法が違ってくるということだ。
新しいツールを使っている一部の人たちは問題を解決できたが、
その他大勢の人たちにとっては新たな問題が増えただけだった。
たとえばOSのパッケージャーは、複数のPython標準規格に対応することが必要になった。
公式に文書化されている標準と、\code{Setuptools}が広めた
デファクトスタンダードの二種類である。

%% But in the meantime, \code{Setuptols} had the opportunity to experiment
%% in a realistic scale (the whole community) some innovations in a
%% very fast pace, and the feedback was invaluable. We were able to 
%% write down new PEPs with more confidence in what worked and what did not,
%% and maybe it would have been impossible to do so differently.
%% So it's all about detecting when some third-party tools are contributing
%% innovations that are solving problems and that should ignite a PEP
%% change.
しかしその一方で\code{Setuptools}には、
現実的な規模(コミュニティ全体)での実験をする機会が与えられた。
そのおかげで短期間に革新が進んだし、貴重なフィードバックが得られた。
新たにPEPを書きおろすときにも何が動いて何が動かないのか確信を持てたし、
他のやり方ではこれほどうまくいかなかっただろう。
もし何かのツールが革新を引き起こそうとしているのなら、
あわせてPEPも変更すべきだ。

\end{aosasect2}

%% \begin{aosasect2}{A Package that Enters the Standard Library Has One Foot in the Grave}
\begin{aosasect2}{標準ライブラリ入りは死への第一歩}

%% I am paraphrasing Guido van Rossum in the section title, but that's
%% one aspect of the batteries-included philosophy of Python that 
%% impacts a lot our efforts.
このセクションのタイトルは、Guido van Rossumの声を言い換えたものだ。
しかしこれもまたPythonの「バッテリー入り」思想の一面であり、
私たちの取り組みに大きな影響を及ぼしている。

%% \code{Distutils} is part of the standard library and \code{Distutils2} 
%% will soon be. A package that's in the standard library is very hard to 
%% make evolve. There are of course deprecation processes, where you can kill 
%% or change an API after 2 minor versions of Python. But once an API is 
%% published, it's going to stay there for years.
\code{Distutils}は標準ライブラリに組み込まれており、
\code{Distutils2}も間もなくその仲間入りする。
いったん標準パッケージに入ってしまうと、そこからさらに成長させることはとても難しくなる。
もちろん廃止手順もあって、Pythonのマイナーリリース2回ぶんの間に
APIの変更や廃止もできるようになっている。
しかし、いったんAPIを公開してしまえば、少なくとも数年間は存在し続けるだろう。

%% So any change you make in a package in the standard library that is 
%% not a bug fix, is a potential disturbance for the eco-system. So when 
%% you're doing important changes, you have to create a new package.
そのため、標準ライブラリのパッケージに対してバグ修正以外の変更をしようとすると、
Pythonの世界に混乱を引き起こす可能性がある。
大きな変更をするなら、新たなパッケージを作る必要がある。

%% I've learned it the hard way with \code{Distutils} since I had to eventually
%% revert all the changes I had done in it for more that a year and create
%% \code{Distutils2}. In the future, if our standards change again in a drastic 
%% way, there are high chances that we will start a standalone \code{Distutils3}
%% project first, unless the standard library is released on its own at some point.
\code{Distutils}でさんざん苦労したおかげで私は学習した。
結局、一年がかりの変更をすべて取り消して、新たに\code{Distutils2}
を作るはめになった。もしまた標準が劇的に変わるようなことがあれば、
どこかで標準ライブラリがリリースされない限りは
\code{Distutils3}プロジェクトを始めることになるだろう。

\end{aosasect2}

%% \begin{aosasect2}{Backward Compatibility}
\begin{aosasect2}{後方互換性}

%% Changing the way packaging works in Python is a very long process: the
%% Python ecosystem contains so many projects based on older packaging
%% tools that there is and will be a lot of resistance to change.
%% (Reaching consensus on some of the topics discussed in this chapter
%% took several years, rather than the few months I originally
%% expected.)  As with Python 3, it will take years before all projects
%% switch to the new standard.
Pythonでのパッケージングの方法を変更するのはとても長い道のりである。
Pythonの世界には、古いパッケージングツールを使っているプロジェクトも多数存在する。
そんな中での変更には、抵抗も多いだろう
(本章でとりあげたようなトピックについての合意に達するのにも、結局は数年がかりだった。
最初は数カ月で済むものだと思っていたのに)。Python 3の時点で
すべてのプロジェクトが新たな標準規格に移行するには数年かかるだろう。

%% That's why everything we are doing has to be backward-compatible with 
%% all previous tools, installations and standards, which makes the 
%% implementation of \code{Distutils2} a wicked problem.
そのため、私たちの試みはすべて、これまでのツールやインストール方法
との後方互換を保つ必要があった。そのおかげで\code{Distutils2}
の実装は苦しいものとなった。

%% For example, if a project that uses the new standards depends on 
%% another project that don't use them yet, we can't stop the installation
%% process by telling the end-user that the dependency is in an unknown 
%% format!
たとえば、新しい標準に従っているプロジェクトがまだそれに対応していない
別のプロジェクトに依存している場合、「依存関係が不明な状態だ」
としてインストールを止めることができなくなってしまう。

%% For example, the \code{INSTALL-DB} implementation contains compatibility code 
%% to browse projects installed by the original \code{Distutils},
%% \code{Pip}, \code{Distribute}, or \code{Setuptools}.
%% \code{Distutils2} is also able to install projects created by the
%% original \code{Distutils} by converting their metadata on the fly.
たとえば\code{INSTALL-DB}の実装には互換性を維持するためのコードが含まれており、
元々の\code{Distutils}や\code{Pip}、\code{Distribute}そして\code{Setuptools}
でインストールされたプロジェクトも閲覧できるようになっている。
\code{Distutils2}も同様で、\code{Distutils}で作ったプロジェクトもインストールできる
ようになっている。旧形式のメタデータをその場で変換しているのだ。

\end{aosasect2}


\end{aosasect1}

%% \begin{aosasect1}{References and Contributions}
\begin{aosasect1}{参考文献と謝辞}

%% Some sections in this paper were directly taken from the various PEP
%% documents we wrote for packaging. You can find the original documents
%% at \url{http://python.org}:
本章のいくつかのセクションは、私たちが書いたPEPドキュメントをそのまま引用したものである。
原文は\url{http://python.org}にある。

\begin{aosaitemize}
  \item PEP 241: Metadata for Python Software Packages 1.0: \url{http://python.org/peps/pep-0214.html}
  \item PEP 314: Metadata for Python Software Packages 1.1: \url{http://python.org/peps/pep-0314.html}
  \item PEP 345: Metadata for Python Software Packages 1.2: \url{http://python.org/peps/pep-0345.html}
  \item PEP 376: Database of Installed Python Distributions: \url{http://python.org/peps/pep-0376.html}
  \item PEP 381: Mirroring infrastructure for PyPI: \url{http://python.org/peps/pep-0381.html}
  \item PEP 386: Changing the version comparison module in Distutils: \url{http://python.org/peps/pep-0386.html}
\end{aosaitemize}

%% I would like to thank all the people that are working on packaging;
%% you will find their name in every PEP I've mentioned. I would also
%% like to give a special thank to all members of The Fellowship of the
%% Packaging.  Also, thanks to Alexis Metaireau, Toshio Kuratomi, Holger
%% Krekel and Stefane Fermigier for their feedback on this chapter.
パッケージングにかかわるすべての人たちに感謝する。
本章で取り上げたすべてのPEPに、君たちの名前が見つかるはずだ。
「パッケージングの仲間」のメンバーにも感謝する。
また、Alexis MetaireauやToshio Kuratomi、Holger Krekel、Stefane Fermigierにも感謝する。
この文章に関するフィードバックをいただいた。

%% The projects that were discussed in this chapter are:
本章で取り上げたプロジェクトを最後にまとめる。

\begin{aosaitemize}
  \item \code{Distutils}: \url{http://docs.python.org/distutils}
  \item \code{Distutils2}: \url{http://packages.python.org/Distutils2}
  \item \code{Distribute}: \url{http://packages.python.org/distribute}
  \item \code{Setuptools}: \url{http://pypi.python.org/pypi/setuptools}
  \item \code{Pip}: \url{http://pypi.python.org/pypi/pip}
  \item \code{Virtualenv}: \url{http://pypi.python.org/pypi/virtualenv}
\end{aosaitemize}

\end{aosasect1}

\end{aosachapter}
